为什么同一程序每次运行时的虚拟内存区域都不同?

为什么同一程序每次运行时的虚拟内存区域都不同?

我正在研究 Linux 中内存区域的虚拟内存映射。可执行文件是一个简单的计数程序。当程序的两个实例运行时,以下是 所示的映射/proc/pid/maps。堆、堆栈、vvar、vdso 等的位置在加载时似乎有随机偏移。为什么要这样做?

实例 1:堆开始于013f4000

00400000-00401000 r--p 00000000 08:16 3557412                            <program-exe>
00401000-00480000 r-xp 00001000 08:16 3557412                            <program-exe>
00480000-004a5000 r--p 00080000 08:16 3557412                            <program-exe>
004a6000-004ac000 rw-p 000a5000 08:16 3557412                            <program-exe>
004ac000-004ad000 rw-p 00000000 00:00 0 
013f4000-01417000 rw-p 00000000 00:00 0                                  [heap]
7ffd98bd8000-7ffd98bf9000 rw-p 00000000 00:00 0                          [stack]
7ffd98bfc000-7ffd98bff000 r--p 00000000 00:00 0                          [vvar]
7ffd98bff000-7ffd98c00000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

实例2:堆开始于013cc000

00400000-00401000 r--p 00000000 08:16 3557412                            <program-exe>
00401000-00480000 r-xp 00001000 08:16 3557412                            <program-exe>
00480000-004a5000 r--p 00080000 08:16 3557412                            <program-exe>
004a6000-004ac000 rw-p 000a5000 08:16 3557412                            <program-exe>
004ac000-004ad000 rw-p 00000000 00:00 0 
013cc000-013ef000 rw-p 00000000 00:00 0                                  [heap]
7ffe3717d000-7ffe3719e000 rw-p 00000000 00:00 0                          [stack]
7ffe371fa000-7ffe371fd000 r--p 00000000 00:00 0                          [vvar]
7ffe371fd000-7ffe371fe000 r-xp 00000000 00:00 0                          [vdso]
ffffffffff600000-ffffffffff601000 --xp 00000000 00:00 0                  [vsyscall]

答案1

这是称为地址空间布局随机化 (ASLR) 的安全功能的结果。当 ASLR 启用时,内核将在随机地址加载关键进程段。所有最新的 Linux 内核都默认启用 ASLR。 ASLR 可以通过 进行控制/proc/sys/kernel/randomize_va_space。来自过程手册页:

/proc/sys/kernel/randomize_va_space (自 Linux 2.6.12 起) 选择系统的地址空间布局随机化 (ASLR) 策略(在支持 ASLR 的体系结构上)。该文件支持三个值:

          0  Turn ASLR off.  This is the default for architectures that
             don't support ASLR, and when the kernel is booted with the
             norandmaps parameter.

          1  Make the addresses of mmap(2) allocations, the stack, and
             the VDSO page randomized.  Among other things, this means
             that shared libraries will be loaded at randomized
             addresses.  The text segment of PIE-linked binaries will
             also be loaded at a randomized address.  This value is the
             default if the kernel was configured with CONFIG_COM‐
             PAT_BRK.

          2  (Since Linux 2.6.25) Also support heap randomization.  This
             value is the default if the kernel was not configured with
             CONFIG_COMPAT_BRK.

因此,要暂时禁用 ASLR,请以 root 身份运行以下命令:

echo 0 > /proc/sys/kernel/randomize_va_space

现在再次运行测试,您应该发现两个进程现在将具有相同的地址映射。

相关内容