katsuhiro > katsuhiro/refmon -> katsuhiro/refmon/ptrace
ptrace 周りの勉強†
ネストされたリファレンスモニタを実現するための ptrace の勉強をここにメモしていく。
返ってこないシステムコール†
来たときの処理†
- sys_rt_sigreturn などの戻ってこないシステムコールのときはコールスタックに情報を積まないようにした。
- 戻ってこないシステムコールを積むとずっと残ってしまう。
具体的な関数名†
リファレンスモニタは監視対象が発行したシステムコールの呼応関係を保持している。そのため呼び出したら返ってこないシステムコールは重要である。それと、フェイント(?)くさい名前のシステムコールもメモしておく。
(確認に用いた環境のカーネルは 2.4.31 である)
返ってくることを確認した
返ってこないことを確認した
- sys_rt_sigreturn
- sys_exit
- 返ってこないのは確かだが、直後に終了してしまうため関係ないかも…。
未確認だがおそらく返ってこない
2.6 系と 2.4 系の差†
一見似たような動きをするけれども CLONE_PTRACE で子プロセスのトレースをしたときに動きが違うかも??2.6 系でもバージョン間で差がありそうなので要確認。
- 2.4.31
- clone(flags | CLONE_PTRACE, ...
- SIGTRAP(at clone の出口)
- SIGSTOP(特に何処ということはなく、適当に飛んでくる)
- SIGTRAP(at 次のシステムコールの入り口)
- 2.6.13.3
- clone(flags | CLONE_PTRACE, ...
- SIGSTOP(at clone の出口)
- SIGTRAP(at 次のシステムコールの入り口)
それと 2.6系では wait 系をエミュレートしなくてもきちんと動いているような気がする。
本当にちゃんと動いているか、要調査。
2.4 と 2.6 系両方で動かすには†
2.4 なら一回目の SIGSTOP を無視しても動いたが、2.6 だと最初の SIGSTOP が SIGTRAP の代わりなので、無視すると clone, fork, vfork の引数書き戻しをせずに進んでしまう。
ptrace の困ったところ†
SIGTRAP でトレースが知らされる†
- 自分自身や、他のプロセスから恣意的に送られた SIGTRAP と、ptrace による SIGTRAP を区別する方法は…?
- 外から SIGTRAP を送りまくると、orig_eax の値によっては、レジスタを書き換えてしまう可能性がある。これはまずそう。
- エイラク神によって、PTRACE_SETOPTIONS の存在を知った。これによって ptrace のトレース時には (SIGTRAP|0x80) という kill では送れないシグナルが来るようになる。
- このオプションがないシステムも考慮したが、そのときは kill で SIGTRAP を送ったときに動作が不安定になるかもしれない。
PTRACE_O_TRACESYSGOOD オプションの使い方†
ptrace(PTRACE_SETOPTIONS, pid, 0, PTRACE_O_TRACESYSGOOD);
- プロセス pid は停止している必要がある。動いているプロセスにやると ESRCH(そのようなプロセスはありません)が帰ってくる。
- ここでもはまった。PTRACE_SETOPTIONS の値が i386/sparc だと 21 ですが(asm/ptrace.h)、linux/ptrace.h をインクルードすると 24 になってて動かない。
- きちんと設定したのに EIO が帰ってくるときは要注意です。i386 なら PTRACE_OLDSETOPTIONS を指定したほうが安心できるかもしれない。