【问题标题】:Why there are holes in the virtual address space of a process为什么进程的虚拟地址空间有漏洞
【发布时间】:2018-12-11 23:53:39
【问题描述】:
我的教科书上说一个虚拟地址空间有很大的漏洞
未映射到任何有意义的数据的过程。但是当我们产生一个执行目标文件时,一切都确定了
例如.text、.data、共享对象等,唯一可能需要有间隙的动态事物是堆栈。那么其他间隙来自哪里?为什么我们不压缩所有东西,只为堆栈留下一个空隙?
另一个问题是,在第二张图上,未分配的 VM 页面和未分配的页面有什么区别?
【问题讨论】:
标签:
linux
process
linux-kernel
virtual-memory
【解决方案1】:
您的图表过于简单化了。这是不正确的:
但是当我们生成一个执行对象文件时,一切都是确定的,例如.text、.data、共享对象等,
文本和数据等内容是可执行文件中的集合。不存在于内存中。
在 64 位系统中,您拥有超过 10 亿 GB 的可寻址空间。现有的应用程序没有接近使用这么多内存,因此地址空间中会有漏洞。
孔用于保护。大多数系统保留未映射的最低页面以创建空指针陷阱。一些系统在堆栈周围设置间隙以捕获上溢和下溢。
有一系列系统地址。这些通常是保留的,但有很多未使用的空间。这会造成漏洞。
如果您尝试保持连续的可用地址范围,则会产生必须保持内存连续的问题。这会产生各种分配问题。
另一个问题是,在第二张图上,未分配的 VM 页面和未分配的页面有什么区别?
我怀疑他们试图说明未映射到地址空间的页面(即完全无效的页面)和分页到辅助存储的页面(即会触发页面的页面)之间的区别访问时出错)。
【解决方案2】:
在第一张图中,虚拟地址空间存在三个间隙。 0 处的洞在那里是因为它很有用;编程bug经常会不小心使用一个小整数作为地址,所以如果地址没有映射到地址空间,MMU硬件可以检测到。
最后的洞是因为我们没有用完所有的地址空间!
共享库之前的漏洞可能有几个原因。在许多架构上,库都有一个“首选”地址来加载;将它们放在其他地方需要重新定位工作,可能还有一些未共享的页面。与所有系统在可预测的地址处都有库 X 相比,“任意”定位它们会使某些黑客攻击更加困难。最后,您忘记了堆 - 一个动态分配内存的区域,通常放置在目标文件分配的数据之后。
在第二张图中,“未分配的 VM 页面”似乎是指页表中没有任何内容的空间。 “未分配的页面”在页表中有条目,因此在某种意义上它们更接近于现有的。不过,我不确定作者想表达什么观点。这对执行程序本身并不重要。
至于为什么地址空间没有被压缩:它没有任何收获。稀缺资源是实际内存,而不是(通常)压缩的地址空间。能够故意留漏洞是一个积极的好处,这样数据可以在必要时扩展。