Linuxでの0番地のmmapについて
http://trackback.blogsys.jp/livedoor/kmckk/1202810
直接リンク先の本題とは関連しないけれど、Linuxでの0番地のmmapについて思い出したことがあるのでちょっとメモしておく。
まず、kernelのソースの fs/binfmt_elf.c の関数load_elf_binary の中にこんなコードがあった。
if (current->personality & MMAP_PAGE_ZERO) { /* Why this, you ask??? Well SVr4 maps page 0 as read-only, and some applications "depend" upon this behavior. Since we do not have the power to recompile these, we emulate the SVr4 behavior. Sigh. */ down_write(¤t->mm->mmap_sem); error = do_mmap(NULL, 0, PAGE_SIZE, PROT_READ | PROT_EXEC, MAP_FIXED | MAP_PRIVATE, 0); up_write(¤t->mm->mmap_sem); }
どういう時かよくわからないけど、SVr4との互換性のために0番地のページをread-only,実行可能でマッピングするケースがある。
それから、以前Ubuntu 8.04でqemuを使うときにmmapがPermisson deniedではじかれたことがあった。
Ubuntu7.10では問題がなかったのにUbuntu8.04ではkernelのバージョンが上がって若いアドレスへのmmapが制限されている。
デフォルトでは最初の64KBの空間への一般ユーザのmmapは禁止されている。sudo すれば可。
ここで話したときのスライドに載せた。(24ページ目)
これの対策は /etc/sysctl.confを以下のように修正してリブートする vm.mmap_min_addr = 65536 -> これを4096に変更 vm.vdso_enabled = 0 を追加
似たようなことがWineでもあるらしい。
Wine problems with new vm.mmap_min_addr setting
要するに最近のkernelでは0番地のページをmmapしようとしたら意識して許可してやる必要があるようだ。
(2009.7.24 追記)
Ubuntu 9.04でwineをインストールすると /etc/sysctrl.d/30-wine.conf というファイルができて、その中身は
$ cat /etc/sysctl.d/30-wine.conf # Wine needs to access the bottom 64k of memory in order to launch # 16 bit programs. vm.mmap_min_addr = 0 $
つまり、0番地からmmapが許可される設定になる。