【问题标题】:Linux - why is the program break pointer (brk/sbrk) different each time a program is run?Linux - 为什么每次运行程序时程序中断指针(brk/sbrk)都不同?
【发布时间】:2015-06-04 05:14:09
【问题描述】:

我了解program break 是 Linux 操作系统为进程分配的最高虚拟内存地址,因此标记了堆的最高地址。您可以通过调用sbrk(0)获取程序中断的地址。

当我创建以下小程序时,每次运行都会得到不同的结果:

#define _BSD_SOURCE
#include <stdio.h>
#include <unistd.h>

int main()
{
    printf( "system break: %p\n", sbrk( 0 ) );
    return 0;
}

例如,在我的电脑上:

$ ./sbrk
system break: 0x81fc000
$ ./sbrk
system break: 0x9bce000
$ ./sbrk
system break: 0x97a6000

我的理解是堆分配在虚拟内存中 BSS 部分的正上方 - 我想我希望它对于像这样的普通程序总是具有相同的初始值。程序中断最初定位的位置是否有一些随机化或某些东西?如果不是,为什么每次运行程序都不一样?

【问题讨论】:

    标签: c linux gcc sbrk


    【解决方案1】:

    默认情况下,内核将随机化初始点,但可以禁用此功能。这是运行的代码(对于 x86,在 arch/x86/kernel/process.c 中):

    unsigned long arch_randomize_brk(struct mm_struct *mm)
    {
            unsigned long range_end = mm->brk + 0x02000000;
            return randomize_range(mm->brk, range_end, 0) ? : mm->brk;
    }
    

    此外,在来自 ELF 二进制加载程序 (fs/binfmt_elf.c) 的这个函数中,您可以看到调用的函数:

    if ((current->flags & PF_RANDOMIZE) && (randomize_va_space > 1)) {
                    current->mm->brk = current->mm->start_brk =
                            arch_randomize_brk(current->mm);
    #ifdef CONFIG_COMPAT_BRK
                    current->brk_randomized = 1;
    #endif
    }
    

    【讨论】:

      【解决方案2】:

      是的,有随机性。称为地址空间布局随机化 (ASLR)。 http://en.wikipedia.org/wiki/Address_space_layout_randomization

      【讨论】:

        猜你喜欢
        • 2014-12-06
        • 2021-12-08
        • 2017-04-17
        • 2021-08-24
        • 2016-05-09
        • 2020-08-05
        • 2016-03-01
        • 2011-10-15
        • 1970-01-01
        相关资源
        最近更新 更多