vxlinux
linux のシステムコールをフックする (DSAS開発者の部屋 2008-07-25)というエントリがあったので、そんなときこそ、vxlinuxと思って試してみたけど、結論から言うとうまく動かすことができなった。
環境はCentOS 5/IA32。binutils/gcc共にソースからコンパイル。
sandboxing環境で実行できるのは静的リンクでコンパイルされた実行バイナリだけなので(Plan9の場合はそれで十分だが)、同梱されているラッパスクリプトvxlinuxgccを使う。
実行結果は次のように、glibcのdouble free checkで引っかかっている。
$ ./hello cd /opt/vx32-0.12/src/vxlinux vxlinux /opt/vx32-0.12/src/vxlinux/_hello eax 00000000 ecx 00000000 edx 00000000 ebx 00000000 esp 080475d0 ebp 00000000 esi 00000000 edi 00000000 eip 08048110 eflags 00000000 *** glibc detected *** ./vxlinux: double free or corruption (fasttop): 0x09673288 *** ======= Backtrace: ========= /lib/libc.so.6[0x700b16] /lib/libc.so.6(cfree+0x90)[0x704070] ./vxlinux[0x80493fa] /lib/libc.so.6(__libc_start_main+0xdc)[0x6addec] ./vxlinux[0x8048a51] ======= Memory map: ======== 00110000-00113000 rwxp 00110000 00:00 0 0027e000-0037e000 rwxp 0027e000 00:00 0 0067a000-00694000 r-xp 00000000 08:03 28049417 /lib/ld-2.5.so 00694000-00695000 r-xp 00019000 08:03 28049417 /lib/ld-2.5.so 00695000-00696000 rwxp 0001a000 08:03 28049417 /lib/ld-2.5.so 00698000-007d5000 r-xp 00000000 08:03 28049419 /lib/libc-2.5.so 007d5000-007d7000 r-xp 0013c000 08:03 28049419 /lib/libc-2.5.so 007d7000-007d8000 rwxp 0013e000 08:03 28049419 /lib/libc-2.5.so 007d8000-007db000 rwxp 007d8000 00:00 0 00e97000-00e98000 r-xp 00e97000 00:00 0 [vdso] 047f7000-04802000 r-xp 00000000 08:03 28049477 /lib/libgcc_s-4.1.2-20080102.so.1 04802000-04803000 rwxp 0000a000 08:03 28049477 /lib/libgcc_s-4.1.2-20080102.so.1 08048000-08054000 r-xp 00000000 08:03 2032967 /opt/vx32-0.12/src/vxlinux/vxlinux 08054000-08059000 rwxp 0000b000 08:03 2032967 /opt/vx32-0.12/src/vxlinux/vxlinux 0966b000-0968c000 rwxp 0966b000 00:00 0 b7e00000-b7e21000 rwxp b7e00000 00:00 0 b7e21000-b7f00000 --xp b7e21000 00:00 0 bf867000-bf87d000 rwxp bf867000 00:00 0 [stack] zsh: abort (core dumped) ./hello
チェックを無効にしても、trap 0xe ページフォルト?でエラー終了する。
う〜む。
$ MALLOC_CHECK_=0 ./hello cd /opt/vx32-0.12/src/vxlinuxvxlinux /opt/vx32-0.12/src/vxlinux/_hello eax 00000000 ecx 00000000 edx 00000000 ebx 00000000 esp 080475bc ebp 00000000 esi 00000000 edi 00000000 eip 08048110 eflags 00000000 eax 080531e0 ecx 00000000 edx 080bd800 ebx 080bd800 esp 08047330 ebp 08047368 esi 00000000 edi 00000000 eip 08048880 eflags 00010297 ./vxlinux: fatal error: vxproc_run trap 0xe
話は変わって、vxlinux内のコードを調べてみた。コアの部分はこんな感じ。fork&exec、ptraceなどで子プロセスを監視する代わりに、vxproc_allocでプロセスの構造体を確保して、vxproc_loadelffileで実行ファイルをロードする。そしてvxproc_runを実行すれば、プロセスが動き出す。そして、何かお痛をすれば、vxproc_runから戻ってくる。その原因がシステムコール(int 0x80)であれば、システムコールのフック処理をする。後はこれの繰り返し。
vxproc *p = vxproc_alloc(); vxproc_loadelffile(p, loadname, &argv[1], (const char**)environ); vx32_siginit(); dumpregs(p); // Simple execution loop. for (;;) { int rc = vxproc_run(p); if (rc < 0) fatal("vxproc_run: %s\n", strerror(errno)); if (rc == VXTRAP_SOFT + 0x80) { dosyscall(p); continue; } dumpregs(p); fatal("vxproc_run trap %#x\n", rc); } return 0; // not reached