220 Views
March 30, 17
スライド概要
Introduction to kprobes, a Linux feature which allows you to set break points in a kernel address space. This presentation also introduces a book about kprobes and sysfs.
サイボウズ・ラボ株式会社で教育向けのOSやCPU、コンパイラなどの研究開発をしています。
kprobesでカーネル空間 ブレークポイント 第6期サイボウズ・ラボユース成果発表会 2017/03/30 @uchan_nos
カーネルモジュール • コンパイル済みオブジェクトファイル • ELF形式のファイル • 動作中のLinuxカーネルに読み込ませられる • $ sudo insmod hello.ko • $ sudo rmmod hello • 自作のプログラムがカーネル空間で動く (カーネルに手を入れずに!) 興奮
Linux カーネルモジュール自作入門 ―kprobes でカーネル空間ブレークポイント― • kprobes = kernel probes • プローブ=探針 • カーネルの任意のアドレスにブレークポイント ブレーク int handler(mod, info) {} …処理… err = move_module(mod, info); …処理… int move_module(mod, info) { … }
プローブの種類 • kprobe • 任意の命令でブレーク • jprobe • 関数の先頭でブレーク • kretprobe • 関数から抜けるときにブレーク
jprobeとは • 関数の入り口だけでブレーク可 • kprobeより自由度が低い代わりに、関数の引数の扱いが楽 struct module *layout_and_allocate(struct load_info *info, int flags) 対象の関数と同じ引数・戻り値型を書くだけ! struct module *handler(struct load_info *info, int flags) { printk(KERN_INFO "%p, %lu\n", info->hdr, info->len); …
jprobeを仕掛けられる関数 • sudo less /proc/kallsyms • ffffffff810ffe00 t setup_load_info • ffffffff811000a0 t module_flags • 関数名と配置アドレス • インライン展開された関数は表示されない
インライン展開の抑制 • カーネルのソースコードを得る • noinline宣言する • static noinline int move_module(…) • 改造後、カーネル再構築 • コンパイルオプション-fno-inlineを付けるのでも良い • が、カーネル全体の動作が遅くなるかも
ダミー関数の挿入 • 関数呼び出し直後の状態を調べたい • noinlineなダミー関数を定義 static noinline void after_move_module( struct module *mod, struct load_info *info, int err) { } • それを希望の場所で呼び出す err = move_module(mod, info); after_move_module(mod, info, err);
レッツ自作モジュール • 是非、kprobesを利用するモジュールを作ってみよう! • 詳しい作り方は本でチェック! Linux カーネルモジュール自作入門 ―kprobes でカーネル空間ブレークポイント― • http://uchan.hateblo.jp/entry/2017/03/22/074801 • この本で扱うこと • • • • Hello Worldモジュールの作成方法 モジュールファイルの内部構造の説明 jprobeでブレークポイントを仕掛ける方法 sysfsを使ってユーザ側から値を受け取る方法