25.1. ASLR と共有オブジェクト

ちなみに malloc を除くと観察眼の鋭い読者はアドレスが違うことも突っ込むかもしれません。

ASLR (Address space layout randomization) は Linux カーネルが自動的に行うセキュリティー対策です。

ASLR はアドレス空間の配置をランダム化するため、ヒープやスタック等のアドレスレイアウトは実行するたびに変わっていきます。

まあ雑学ですが試しにやってみましょう。

$ gcc empty.c
$ file ./a.out
./a.out: ELF 64-bit LSB shared object, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=3442e99a7a1f9aedf7d82e9b190bb77b1773a049, not stripped
$ strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffded1e1640 /* 57 vars */) = 0
brk(NULL)                               = 0x555da594e000
....
$ strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffd2af313d0 /* 57 vars */) = 0
brk(NULL)                               = 0x5649fc562000
....
$ strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffefd873730 /* 57 vars */) = 0
brk(NULL)                               = 0x55e0e79e2000

表示されるアドレスはどの回も全て違いますよね?

ビルド時にポジション独立のフラグを削ったらどうでしょうかね?

$ gcc empty.c -no-pie
$ file ./a.out
./a.out: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, for GNU/Linux 3.2.0, BuildID[sha1]=0e84efc9f16719b1f2f3ca031ee8c33c555a46ca, not stripped
$ strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffc46b88170 /* 57 vars */) = 0
brk(NULL)                               = 0xf83000
....
$ strace ./a.out
execve("./a.out", ["./a.out"], 0x7fffa75f73b0 /* 57 vars */) = 0
brk(NULL)                               = 0x162e000
....
$ strace ./a.out
execve("./a.out", ["./a.out"], 0x7ffccc7592c0 /* 57 vars */) = 0
brk(NULL)                               = 0x1854000
....

アドレスは毎回違いますが brk(NULL) のコールは毎回違ってるだけでなく、アドレスがポジション依存になっていることが見て取れます。

Copyright 2018-2019, by Masaki Komatsu