ptraceされているプロセスはsetuidの昇格が無効化される
Linuxでは、ptraceでトレースされているプロセスがexecve(2)でsetuid/setgidビット付きの実行ファイルを実行しても、実効ユーザーID(EUID)の昇格が行われない。man straceのBUGSセクションに一次情報として明記されている。
Programs that use the setuid bit do not have effective user ID privileges while being traced.
strace自身のオプション--user=usernameの説明にも同じ制約が書かれている。「strace自身がroot権限で動いている場合のみ有効なオプションで、それ以外の場合、setuid/setgidプログラムは実効特権なしで実行される」という趣旨。
なぜこの制約があるか
setuidバイナリは「実行した瞬間にroot(など他ユーザー)の権限に切り替わる」ことが前提の仕組み。もしトレーサー(ptraceする側)がトレーシー(される側)のメモリ・レジスタを自由に読み書きできる状態のまま昇格を許してしまうと、非特権ユーザーがトレーサー経由でroot権限のプロセスの実行内容を覗き見・改竄できてしまい、setuidの権限分離が意味を失う。この問題は歴史的に実際の脆弱性(ptrace/setuid実行のレースコンディションによる権限昇格)として悪用された経緯があり、その対策として「トレースされている間はsetuidによる昇格自体を止める」という設計になっている。
手を動かして確認したこと
fuse-hello-world実験で、非rootユーザーのプロセスがfusermount3(setuid-rootのFUSEマウントヘルパー)をfork・execする場面をstrace -fでトレースしたところ、通常は成功するはずのfusermount3側のmount(2)システムコールまでEPERM(Operation not permitted)で失敗する挙動を実際に観測した。strace -fがfusermount3のexecve後もトレースを継続する(=fusermount3もトレースされたまま動く)ため、setuidによる昇格が無効化され、fusermount3が非特権のままmountを試みて失敗した、という説明と一致する結果だった。
Linuxの権限分離・権限昇格の仕組みの中での位置づけ
ptraceとsetuid / setgidという2つの仕組みが、なぜ・どう交わらないよう設計されているかを具体的な観測付きで示す、両ノートの交点にあたる内容。
出典
man strace(BUGSセクション、--userオプションの説明)