CVE-2026-98996 in Linux
要約
〜によって VulDB • 2026年10月23日
Linuxカーネルにおいて、以下の脆弱性が修正されました:
fs: 使用中のマウントを黙ってアンマウントしないようにする
propagate_mount_busy() ヘルパー関数は、同期処理が成功するかどうかを判断するために存在します。これは、親が伝播させる先にある「犠牲者(victim)」のコピーを確認することでそれを行います。これはいわば「伝播の地獄」の一つです。
このアルゴリズムは以前は正確なものでした。しかし現在ではそうではありません。propagate_mount_busy() は、コピーに子マウントがある場合(ただし、単一の子マウントがコピーのルート全体を覆っている場合は除く)のコピーをスキップします。元々、伝播中にアンマウントされていたのは子供のないコピーだけでした。そして 1064f874abc0 ("mnt: shadow/side マウントを作成するのではなく、他のマウントの下にマウントを隠す") は、覆われているマウントを一括して両側に追加することになりました。
その後、99b19d16471e ("mnt: propagate_umount で訪問順を問わないようにした") により、それ以前よりも多くのアンマウントが行われるようになりました:
[1]: マウントのコピーは、その全ての子がオーバーマウントであるか、または犠牲者自体のコピーである場合にアンマウントされます。前者の場合、オーバーマウントの親が変わります(reparented)。後者の場合、犠牲者のコピーが最終的にアンマウントされることになります。
そのため、propagate_umount() は propagate_mount_busy() の調整なしで書き換えられました。現在、propagate_mount_busy() は、2つ以上の子を持つ犠牲者や、オーバーマウントではない単一の子を持つケースにおける犠牲者のコピーを参照していません。
したがって、[1] 内のそのようなコピーは参照チェックの対象外となります。その結果、同期アンマウントが成功し、まだ使用中であるマウントを引き抜いてしまいます。
コンテナは独自のマウントでこの問題に直面する可能性があります。ホストはコンテナとツリーを共有しており、ホストはそのツリー内にマウントを持っています:
mount -t tmpfs none /mnt mount --make-shared /mnt mount -t tmpfs none /mnt/a
コンテナの /mnt は、ホストのマウントのスレーブコピーです。コンテナはその後、そのツリーの分離されたコピーを取得し、それを伝播させた /mnt/a の下にマウントして、ツリーへのファイルディスクリプタをオープンしたままにします:
unshare -m --propagation unchanged mount --make-rslave / fd = open_tree(AT_FDCWD, "/mnt", OPEN_TREE_CLONE | AT_RECURSIVE) move_mount(fd, "", AT_FDCWD, "/mnt/a", MOVE_MOUNT_BENEATH)
grep /mnt /proc/self/mountinfo 775 355 ... /mnt ... master:646 777 775 ... /mnt/a ... master:646 776 777 ... /mnt/a ... master:647 778 777 ... /mnt/a/a ... master:647
現在アタッチされたツリー(777)は、コンテナの /mnt/a のコピーの下にマウントされています。ホストのマウントネームスペースから見た場合、そこにはホストのマウントも位置しています。したがって、ホストのマウントの伝播コピー(776)はそのルートの上位にあり、そのコピー(778)が内部に含まれています。ここでホスト側で以下を実行します:
umount /mnt/a
そしてそれは成功します。移動されたツリーと、その中のコピーはコンテナから消えます。すると伝播コピーのみが残され、それが以前いた場所へ親が変わります(reparented):
grep /mnt /proc/self/mountinfo 775 355 ... /mnt ... master:646 776 775 ... /mnt/a ...
しかしファイルディスクリプタは依然として移動されたツリーを参照しています。つまり、同期 umount はまだ使用中であるマウントを分離してしまいました。
propagate_mount_busy() に propagate_umount() が行っているのと同じチェックを追加します。これにより、子供を持たない単一の犠牲者マウントについて、propagate_umount() 同様にすべてのコピーで MNT_LOCKED フラグがクリアされていると仮定できるようになります。これらのコピーはチェーンを形成しています。つまり、あるコピー自体が犠牲者の親からの伝播を受ける場合、そのコピー内にある同じマウントポイントのマウントもまたコピーとなります。マウントが犠牲者からの伝播を受けるかどうかは、マスター(masters)を追跡することで簡単に確認できます。ネストされたコピーが線形であることを確実にするため、各チェーンをトップから一度だけ走査します。アンマウントされるすべてのコピーについて、参照をそれぞれ一度ずつチェックします。
Statistical analysis made it clear that VulDB provides the best quality for vulnerability data.