为什么强制执行内存权限需要这么长时间?

信息安全 记忆 部门
2021-09-11 18:20:53

来自DEP上的 Wikipedia 页面

DEP 于 2004 年在 Linux(内核 2.6.8[2])上引入,2004 年在 Windows 上使用 Windows XP Service Pack 2,[3] 而 Apple 在 2006 年迁移到 x86 时引入了 DEP。

为什么直到 2004 年 DEP 发布时才在硬件中正确执行内存页面访问标志?硬件或软件架构中是否有任何限制使其变得困难?

2个回答

这主要是硬件制造商方面的成本效益分析问题,以及代表操作系统供应商的风险分析问题。

x86 架构早在 80386 就已经提供了内存页面访问权限,但当时在硬件中实施这种硬件实施成本很高,并且被认为没有必要。对于大多数用户和大多数小型企业来说,计算机已经非常昂贵,因此硬件制造商不想为了客户不理解或不关心的功能而增加成本。

随着时间的推移,这种自满情绪变得更加明显。缓冲区溢出的时代已经来临,它开始伤害大企业。到 2003 年,计算机安全已被证明是一个具有商业利润的领​​域,硬件价格已降至商品水平。AMD 和 Intel 最终决定硬件执行是一项有利可图的功能,因此他们在 2004 年初实施了 Never eXecute (NX)。AMD 发布了支持 NX 的 Athlon XP-M “Dublin”,第一个支持它的 Intel 处理器是 Pentium 4 普雷斯科特(E0 版)。然而,在这一点上,NX 处理器的市场份额很小。

软件实施的主要障碍是必须在 NX 可用之前启用和支持物理地址扩展 (PAE)。这意味着对操作系统内核内的核心内存管理进行了广泛的更改。

软件方面的另一部分问题是编写不佳的应用程序。一些代码依赖于错误地执行未放置在标记为可执行的内存页面中的数据的能力。随着内存访问标志的硬件实施的出现,这些程序将引发访问冲突。在继续进行更改之前,需要仔细考虑这些好处。DEP 作为一个没有硬件支持的概念,在较早的时候被认为是 Linux 的潜在特性,但由于复杂性问题、破坏性更改以及软件执行机制很容易被绕过的事实而被拒绝。

一旦硬件支持可用,就必须修改操作系统才能使用它。这不是一项微不足道的任务。DEP 将某些重要的结构(例如堆栈和堆)标记为不可执行。这需要修改处理创建线程和进程的每个初始化例程以支持 NX,以及对内存管理(例如堆分配)进行某些更改。最后,必须修改一些硬件抽象层代码,以便正确识别支持处理器上的 NX 标志。

总而言之,这实际上发生得惊人地快。一旦硬件 NX 实施可用,Windows XP 和 Linux 都在 8 个月内发布了与 NX 兼容的版本。

有两个原因:(a) 安全性不是一个重要的优先事项,以及 (b) 32 位与 64 位架构的差异。

NX 位仅在 64 位架构上受支持。NX 位提供页面级别的执行权限,因此操作系统可以将某些页面标记为不可执行。NX 位是使某些页面不可执行的标准方式,因此是实现 DEP 的标准和最干净的方式。然而,64 位架构需要一段时间才能普及,因此只有在许多人开始使用 64 位架构时,在操作系统中实现对基于 NX 位的 DEP 的支持才对安全性产生重大影响。

因此,由于 64 位架构的缓慢采用,DEP 的实施在一定程度上减慢了速度。(如果 32 位 Intel 平台支持 NX 位,我们可能已经看到了 DEP 的早期部署——但它没有,所以我们没有。)DEP 直到 64 位 Intel/AMD 芯片才普及变得普遍。所以,这就是为什么 DEP 花了这么长时间才普及的原因。


好的,现在我承认上面的内容有点过于简单化了——尽管不是太多。事实上,有一种方法可以在 32 位架构上实现 DEP,但它要困难得多,并且不能很好地与大多数操作系统的当前构建方式相结合。

在 32 位 Intel 架构上,实际上有两个不同的内存保护机制:页级保护和段级保护。大多数操作系统依赖页级机制(页表等)来保护内存。页面级机制是最灵活的,因为每个页面都可以有自己的保护级别(例如,只读与读/写;用户可访问与仅内核)。但是,32 位 Intel 处理器也支持基于段的内存保护。段是内存的连续区域,您可以有几个不同的段。每个段都可以接收自己的保护访问。因为页级保护更加灵活,所以大多数操作系统不使用段级保护(它们有效地将内存视为一个大段,并轮流分段)。

由于某些未知的原因,在 32 位架构上,段级保护确实允许将段标记为不可执行,但页级保护机制不允许将页面标记为不可执行。(我不知道为什么,它可能只是历史的产物。)这意味着可以通过使用段级保护在 32 位架构上实现 DEP。但是,这需要对操作系统进行各种扭曲和重大更改。这样做会变得非常混乱和复杂,并且还会对性能产生一些影响。由于这个原因,许多操作系统不愿意在 32 位架构上实现 DEP。

因此,说 DEP 在 32 位架构上是不可能的并且首先在 64 位架构上成为可能并不十分准确——但是,出于工程目的,它非常接近事实。