livepatch - 概念と技法



http://ukai.jp/Software/livepatch

Binary 2.0 Conference @ Tokyo

Fumitoshi UKAI / 鵜飼文敏 / ukai@debian.or.jp, ukai@debian.org

はじまり

15

今日のプレゼンはmop改造版; timer+progress barつき↑

1 years and a month ago...


それはあるIRCちゃねるでの会話ではじまった

on IRC

30
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があるじゃないか

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に置きかえたい



これは簡単じゃない

ターゲットでのメモリの確保

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ライブラリ


外部ダイナミックリンク

まとめ

20


危ない! 変なパッチすると即死
最初からサービスが継続できるようなdaemonを作るべきでは?
Happy Hacking!
Write Great Code!