Binary 2.0 Conference @ Tokyo
Fumitoshi UKAI / 鵜飼文敏 / ukai@debian.or.jp, ukai@debian.org
今日のプレゼンはmop改造版; timer+progress barつき↑
19:45 <g****> というよりこの前のカーネルカンファレンス
19:45 <g****> あれを発表したコムウェアは勇者だとまじでおもった(わら
19:46 <g****> いやこう 技術的に もうやりたい放題?
19:47 <g****> ありえねえ ということをやってた
19:50 <g****> あれをやれといわれたら 洩れは逃亡するな
19:50 <g****> まああれはむごかった
19:51 <g****> developer.osdl.jp/projects/pannus/
19:51 <g****> これですよ
19:51 <k****> キャリアグレードか
19:51 <g****> メモリイメージを直接書き換えるために mmap3 を追加したとか
19:52 <g****> タスクをとめるために直接スケジューラいじったりとか
19:52 <g****> SMP とかなにもかんがえてないとか
19:52 <g****> まあカーネルが何かわかってないと
19:52 <g****> だまされる講演かしら
19:52 >ukai< む live patching
what is livepatch?
15
live patchingとは
実行中のプロセスを
再起動せずにパッチ
をあてる技術のこと
livepatchは live patchingのユーザレベルの一実装
livepatch requirements
40
実行中のプロセスのコードとデータを別のプロセスから修正 すること
マルチタスクオペレーティングシステム
プロセスはそれぞれ独自のメモリ空間をあたえられ他から見えない
ということは、別のプロセスが修正するのは不可能?
それを実現する新しいsyscall, APIが必要?
No!既にそれをやるツールおよびsyscallがあるじゃないか
- gdb、ptrace(2)
ptrace(2)
20
ptraceシステムコール
ptrace - process trace SYNOPSIS long ptrace(enum __ptrace_request request, pid_t pid, void *addr, void *data); DESCRIPTION The ptrace system call provides a means by which a parent process may observe and control the execution of another process, and examine and change its core image and registers. It is primarily used to implement breakpoint debugging and system call tracing.SunOS のマニュアル・ページには ptrace は独特で不可解と記述されており、まさしくそうである。使っているrequest
20
- PTRACE_ATTACH
- プロセスにアタッチ
- PTRACE_DETACH
- プロセスをデタッチ
- PTRACE_PEEKTEXT, PTRACE_PEEKDATA
- プロセスのメモリを読む
- PTRACE_POKETEXT, PTRACE_POKEDATA
- プロセスのメモリに書く
- PTRACE_SETREGS, PTRACE_GETREGS
- プロセスのレジスターを読み書き
- PTRACE_CONT
- プロセスを実行
単純なlive patching
25
- PTRACE_ATTACH
- ターゲットプロセスにアタッチ。ターゲットプロセスは停止する。waitでまつ
- PTRACE_PEEKDATA と PTRACE_POKEDATA
- ターゲットプロセスのメモリを読み書きする
- PTRACE_DETACH
- ターゲットプロセスをデタッチ。実行を継続
複雑なlive patching
30
bugを修正した関数を含むnewfunc.soに置きかえたい
これは簡単じゃない
- newfunc.so をおくメモリをターゲットプロセスに確保
- newfunc.so を確保されたメモリにリロケート
ターゲットでのメモリの確保
35
ptrace(2)にはそのようなrequestはない
そのようなrequestを新設しないとだめなのだろうか?
trick!メモリはmmap(2)によって割りあてることができる
mmap(NULL, length, PROTO_READ|PROTO_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
このコードをターゲットにおくりこんで実行させれば、OK!
引数をスタックにつんで int $0x80 を実行するだけ
see livepatch.c:target_alloc()
リロケーション
35
BFDライブラリ - Binary File Descriptorライブラリ
外部ダイナミックリンク
- /proc/$$/mapsからファイルごとのvmaを調べる
- ファイルをBFDライブラリでよむ
- シンボルのvmaをmapsのvmaに従ってリロケート
- newfunc.soを新たに確保したメモリにリロケート&リゾルブ
- 確保したメモリにそのデータを書きこむ
まとめ
20
- ptrace(2)
- 黒魔術システムコール 〜 独特で不可解
- mmap(2)コードインジェクションによりメモリ確保
- BDFライブラリ
- /proc/$$/maps で メモリ割り当て状況を知る
- 外部ダイナミックリンク
危ない! 変なパッチすると即死
最初からサービスが継続できるようなdaemonを作るべきでは?
Happy Hacking!Write Great Code!