我在 linux 3.16.0-29-generic 上使用 gcc。
我设法使用 gcc -Wl,--section-start=.text=0x201000
选项指示 gcc 编译器设置为我正在编译的代码的加载地址 0x201.000(似乎ELF 的 header 需要 0x1000,所以我不能低于 0x201.000)。
而不是在其他测试中使用 mmap
,我已经能够分配较低的地址,例如有时 0x10.000 从不从 0x0.000 到 0xF.000,并且总是所有其他地址达到和超过 0x800.000 )。
因此,我要问的是,从操作系统用户的角度来看,哪些地址可用于通用进程,以及为什么可执行文件不能加载到 0x200.000 以下?
它在哪里记录或我应该在哪里查看。 是否保证某些虚拟内存应该始终存在?在任何请求的地址(除非物理内存不足?)。 本质上,问题是“进程可用的线性内存是什么”,或者换句话说,提供给开发人员的逻辑模型是什么?
最佳答案
关于无法映射 0x10.000 以下的地址,答案在“https://wiki.ubuntu.com/Security/Features”中。
0地址保护
由于内核和用户空间共享虚拟内存地址,因此需要保护“NULL”内存空间,以便用户空间 mmap 的内存不能从地址 0 开始,从而阻止“NULL 取消引用”内核攻击。这对于 2.6.22 内核是可能的,并且是通过“mmap_min_addr”sysctl 设置实现的。从 Ubuntu 9.04 开始,内核中内置了 mmap_min_addr 设置。 (x86 为 64k,ARM 为 32k。)
我们可以使用指令 sudo sysctl -w vm.mmap_min_addr=0
所以答案是整个地址空间无一异常(exception)地可用(线性地址)。
关于c - 为什么我无法加载 0x201.000 以下的可执行文件(哪个线性地址空间在 linux 进程中被视为可用?它记录在哪里?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28053302/