CVE-2026-43494 / PinTheft:Linux RDS と io_uring が組み合わさるローカル権限昇格リスク

CVE-2026-43494 / PinTheft の要点を整理する。Linux RDS zerocopy の参照カウント問題が io_uring fixed buffer と組み合わさってローカル権限昇格チェーンになる仕組みと、管理者が前提条件を確認し、露出を下げ、ディストリビューションの修正を待つための観点をまとめる。

CVE-2026-43494 は Linux カーネルのローカル権限昇格リスクです。関連する悪用チェーンは PinTheft とも呼ばれています。重要なのはリモート入口ではなく、低権限のローカルユーザーが RDS zerocopy、io_uring fixed buffer、読み取り可能な SUID-root プログラム、そして該当するカーネルバージョンを同時に満たせるかどうかです。

まず番号の扱いを整理しておきます。Unclecheng-li/poc-lab リポジトリのディレクトリ名は CVE-2026-43494 PinTheft ですが、README のタイトルには QVD-2026-27616 - PinTheft も書かれています。公開 CVE エントリと第三者アドバイザリを見る限り、CVE-2026-43494 は Linux kernel RDS zerocopy において op_nents が正しくリセットされず、double-free / 参照カウント異常につながる問題を指します。QVD-2026-27616 は Qianxin 側のリスクアドバイザリ番号に近いものと考えられます。実際の調査では両方の識別子を記録しつつ、ディストリビューションのセキュリティ告知とカーネルパッチ状況を基準にしてください。

脆弱性の核心は何か

この問題は Linux RDS、つまり Reliable Datagram Sockets の zerocopy 送信パスにあります。公開情報で挙げられている主要な関数は次の通りです。

1
2
rds_message_zcopy_from_user()
rds_message_purge()

rds_message_zcopy_from_user() の中で iov_iter_get_pages2() が失敗すると、すでに pin されたページがエラーパスで解放されます。しかし関連する op_nents の状態が正しくクリアされないため、後続の rds_message_purge() が残ったエントリに基づいてもう一度解放してしまう可能性があります。結果として、同じページ参照群のカウントが過剰に減り、悪用可能な参照カウントエラーになります。

RDS の bug だけを見れば、これはカーネル内部のメモリ管理におけるエラーパス問題です。PinTheft が危険なのは、この問題を io_uring の固定バッファ機構につなげる点にあります。io_uring は古い struct page * を保持したままですが、そのページ自体はすでに解放され、別用途に再割り当てされています。公開 PoC はこの状態を SUID-root プログラムの page cache 上書きへ誘導し、最終的にローカル権限昇格に到達します。

なぜ PinTheft と呼ばれるのか

io_uring REGISTER_BUFFERS はユーザーページを固定します。通常のページに対して、FOLL_PIN は単純な参照カウントの 1 増加ではなく、大きな bias によって page refcount を増やします。公開 PoC では GUP_PIN_COUNTING_BIAS = 1024 という概念が使われています。

PinTheft という名前は、攻撃チェーンが RDS zerocopy の失敗パスを通じて、これらの pin 参照を何度も「盗む」ことを意味します。参照が消費された後も、io_uring は自分が有効なページを保持していると考えますが、その物理ページはすでに解放され、page cache に再利用され得ます。

この種の脆弱性は「ディスク上の /usr/bin/su を直接書き換える」と誤解されがちです。より正確には、悪用チェーンが上書きしようとするのはメモリ上の page cache です。ファイル本体がディスクへ書き戻されるとは限りませんが、カーネルがその SUID プログラムを実行するとき、汚染されたページキャッシュから命令を読み出し、攻撃ペイロードを実行する可能性があります。

発火条件は広くない

これは「任意の Linux サーバーをリモートから攻撃できる」タイプの脆弱性ではありません。公開情報によると、悪用チェーンは少なくとも次の条件に依存します。

  • カーネルで CONFIG_RDSCONFIG_RDS_TCP が有効。
  • システムで CONFIG_IO_URING が有効で、kernel.io_uring_disabled=0
  • rds / rds_tcp モジュールがすでにロード済み、または低権限ユーザーが自動ロードを誘発できる。
  • /usr/bin/su/usr/bin/passwd/usr/bin/pkexec など、読み取り可能な SUID-root バイナリがローカルに存在する。
  • 公開 PoC は比較的新しい IORING_REGISTER_CLONE_BUFFERS API にも依存する。CloudLinux の分析では、公開 PoC は kernel 6.13 以降により近い形だと説明されている。

このうち一つでも欠ければ、公開されている悪用経路は途切れます。たとえば多くの RHEL 系ディストリビューションは標準で RDS をコンパイルしておらず、古い Ubuntu カーネルには PoC が必要とする io_uring clone buffer API がない場合があります。また、一部の環境では非特権ユーザーによる RDS モジュールの自動ロードが制限されています。

1 分でできる確認

まずカーネル設定を確認します。

1
2
zgrep -E "CONFIG_(RDS|RDS_TCP|IO_URING)" /proc/config.gz 2>/dev/null \
  || grep -E "CONFIG_(RDS|RDS_TCP|IO_URING)" /boot/config-$(uname -r)

次に io_uring が無効化されているか確認します。

1
cat /proc/sys/kernel/io_uring_disabled 2>/dev/null

よくある値は次のように見ます。

  • 0:使用可能で、露出面が最も大きい。
  • 1:非特権ユーザーの利用を制限。具体的な挙動はカーネルバージョンとディストリビューションの方針による。
  • 2io_uring を無効化。

RDS モジュールが存在し、ロード可能かも確認します。

1
2
lsmod | grep -E "^rds|^rds_tcp"
modprobe -n -v rds_tcp 2>&1 | head -3

CONFIG_RDSnot set の場合、またはシステムに rds_tcp モジュールがまったくない場合、通常はこの bug に到達できません。逆に RDS が利用可能で、io_uring が無効化されておらず、比較的新しい汎用カーネルを使っている場合は、ディストリビューションの修正状況を優先して確認すべきです。

優先して確認したいマシン

次の環境を優先してください。

  1. 複数ユーザーの Linux ホスト、教育用マシン、踏み台、共有開発機。
  2. コンテナホスト。特に信頼できないローカルユーザーを許可する環境や、コンテナ脱出面が緩い環境。
  3. Arch のような rolling distribution など、新しめの mainline / rolling kernel を使うデスクトップやサーバー。
  4. HPC、Oracle RAC、その他 RDS を実際に使う可能性のある場面。
  5. 非特権ユーザーが大量のローカルコードを実行できる CI worker、ビルドマシン、実験環境。

通常の Web サーバーで、管理されたサービスアカウントだけがアプリケーションを実行し、RDS も有効でない場合、実際のリスクはかなり下がります。ただし「かなり低い」は「対応不要」ではありません。カーネルのローカル権限昇格では、攻撃者がまず Web、SSH、CI、コンテナ、アプリケーション脆弱性などで低権限を得て、その後ローカル bug で制御範囲を広げる、という流れが典型です。

一時的な緩和策

正式な修正は、引き続きディストリビューションのカーネル更新を基準にしてください。パッチ、バックポート版、影響範囲は Debian、Ubuntu、RHEL、AlmaLinux、Rocky Linux、SUSE、Arch、クラウドベンダー、コンテナベースイメージ提供元などの各セキュリティ告知で確認する必要があります。上流のバージョン番号だけで判断しないでください。

パッチ待ち、またはすぐにカーネルを再起動できない場合は、環境に応じて一時対策を選べます。

1
2
3
4
5
# 業務が RDS に依存していない場合、関連モジュールのロードをブロックする
sudo sh -c "printf 'install rds /bin/false\ninstall rds_tcp /bin/false\ninstall rds_rdma /bin/false\n' > /etc/modprobe.d/pintheft.conf"
sudo rmmod rds_tcp 2>/dev/null
sudo rmmod rds_rdma 2>/dev/null
sudo rmmod rds 2>/dev/null

業務が io_uring に依存していない場合は、無効化または制限も検討できます。

1
sudo sysctl -w kernel.io_uring_disabled=2

永続化するには、対応する /etc/sysctl.d/*.conf に設定を書き込みます。ただしこの手順は慎重に扱う必要があります。現代的なデータベース、プロキシ、ランタイム、高性能 I/O プログラムは io_uring を使っている可能性があります。本番環境で変更する前に、業務依存を確認してください。

修正後の検証

カーネルを更新した後は、パッケージマネージャーの成功表示だけで済ませないでください。次の三つを確認することを推奨します。

1
2
3
uname -a
cat /proc/sys/kernel/io_uring_disabled 2>/dev/null
modprobe -n -v rds_tcp 2>&1 | head -3

ディストリビューションの告知で CVE-2026-43494 が修正済みと明記されていれば、uname -r が最新の上流版に見えなくても、安定版カーネルにバックポート済みの可能性があります。逆に、カーネルの入手元が自前ビルド、第三者リポジトリ、クラウドマーケットプレイスイメージ、コンテナホストテンプレートの場合は、パッチ commit とビルド時刻を引き続き照合してください。

参考情報

记录并分享
Hugo で構築されています。
テーマ StackJimmy によって設計されています。