今回はexecveの中を流れを追ってみる。
- @mmitou がexecve観察用のSystemtapスクリプトを書いてきてくれた(https://gist.github.com/3433352)
- 「SystemTap」とは簡単なスクリプトを書くことで、稼働中のLinuxカーネルに対して実行情報を取得するためのツール。
- Macの時はDTraceを使うと良い。Windowsはしらん。
- do_execve(linux-3.4.4/fs/exec.c:1584)
- do_execve_common(/linux-3.4.4/fs/exec.c:1457)
- unshare_files(linux-3.4.4/kernel/fork.c:1829)
- prepare_bprm_creds(linux-3.4.4/fs/exec.c:1188)
- prepare_exec_creds(linux-3.4.4/kernel/cred.c:332)
- prepare_creds(linux-3.4.4/kernel/cred.c:285)
- prepare_exec_creds(linux-3.4.4/kernel/cred.c:332)
- open_exec(linux-3.4.4/fs/exec.c:765)
- search_binary_handler(linux-3.4.4/fs/exec.c:1369)
- load_elf_binary(linux-3.4.4/fs/binfmt_elf.c:556)
- start_thread(linux-3.4.4/arch/x86/kernel/process_32.c:192)
- load_elf_binary(linux-3.4.4/fs/binfmt_elf.c:556)
- do_execve_common(/linux-3.4.4/fs/exec.c:1457)
- システムコールからハンドリングした先として呼ばれる関数
- 中はdo_execve_commonを呼んでるだけ
- プロセス実行の一連の処理を行なう関数
- linux_binprmはユーザー空間にある引数をカーネル側で保持・加工する為に使う構造体
linux_binprm(linux-3.4.4/include/linux/binfmts.h:28) - http://hira-consulting.com/wiki/index.php?linux_binprm%2Flinux2.6
- ファイルディスクリプタを管理している構造体を複製して、unshare(非共有状態)にする
- プログラムを実行する前のセキュリティチェック?
- linux-3.4.4/Documentation/security/credentials.txt
- リーディング前はプロセスの実行をここでやっているのかと思っていたが、ただファイルを開いてるだけだった
- 実行バイナリをロードするためのハンドラを探しだしそれを実行する関数
- linux_binfmtはbinaryloadやcoredumpのハンドラの情報を持った構造体。
- linux-3.4.4/include/linux/binfmts.h:86
- 実行バイナリフォーマット(ELF等)毎にlinux_binfmtのインスタンスが定義される
- 例えばELFの場合は linux-3.4.4/fs/binfmt_elf.c:69
- linux_binfmtを取得できたら、その後list_for_each_entry内でハンドラを取得してfn変数に代入。
- (linux-3.4.4/fs/exec.c:1400)で実行バイナリをロードをしている
- コンテキストスイッチをした時にどこから始まるかという情報を持たせている関数
- 呼び出し引数
- struct pt_regs * regs: レジスタの情報
- unsigned long pc: エントリポイントのアドレス
- unsigned long sp: ランダマイズされたスタックポインタのアドレス
- 呼び出し引数
- togetter: http://togetter.com/li/361350
- 次回はプロセスのライフルサイクルの最後exit。担当は @r_takaishi