[[katsuhiro]] > [[katsuhiro/refmon]] -> [[katsuhiro/refmon/ptrace]] [[katsuhiro]] > [[katsuhiro/refmon]] -> katsuhiro/refmon/ptrace *ptrace 周りの勉強 [#be698a7a] ネストされたリファレンスモニタを実現するための ptrace の勉強をここにメモしていく。 **返ってこないシステムコール [#u78dffcf] ***来たときの処理 [#jacbaa3e] -sys_rt_sigreturn などの戻ってこないシステムコールのときはコールスタックに情報を積まないようにした。 --戻ってこないシステムコールを積むとずっと残ってしまう。 ***具体的な関数名 [#td37cb87] リファレンスモニタは監視対象が発行したシステムコールの呼応関係を保持している。そのため呼び出したら返ってこないシステムコールは重要である。それと、フェイント(?)くさい名前のシステムコールもメモしておく。~ (確認に用いた環境のカーネルは 2.4.31 である)~ 返ってくることを確認した -sys_exitgroup 返ってこないことを確認した -sys_rt_sigreturn -sys_exit --返ってこないのは確かだが、直後に終了してしまうため関係ないかも…。 未確認だがおそらく返ってこない -sys_sigreturn **2.6 系と 2.4 系の差 [#sb4b95ed] 一見似たような動きをするけれども 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 系両方で動かすには [#lbddb286] 2.4 なら一回目の SIGSTOP を無視しても動いたが、2.6 だと最初の SIGSTOP が SIGTRAP の代わりなので、無視すると clone, fork, vfork の引数書き戻しをせずに進んでしまう。 **ptrace の困ったところ [#s171ca9f] ***SIGTRAP でトレースが知らされる [#p6c446f1] -自分自身や、他のプロセスから恣意的に送られた SIGTRAP と、ptrace による SIGTRAP を区別する方法は…? --外から SIGTRAP を送りまくると、orig_eax の値によっては、レジスタを書き換えてしまう可能性がある。これはまずそう。 -エイラク神によって、PTRACE_SETOPTIONS の存在を知った。これによって ptrace のトレース時には (SIGTRAP|0x80) という kill では送れないシグナルが来るようになる。 -このオプションがないシステムも考慮したが、そのときは kill で SIGTRAP を送ったときに動作が不安定になるかもしれない。 ***PTRACE_O_TRACESYSGOOD オプションの使い方 [#o45c8be8] 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 を指定したほうが安心できるかもしれない。