引言
内存覆盖和地址错误使非常难以诊断和处理的问题。随着软件的大小以及复杂程度不断增加,情况变得更为复杂。在 aix? 操作系统中,许多软件组件共享内核地址空间。
现在,power6? 处理器和 aix version 6.1 提供了存储保护键,其中可以使用内核扩展和设备驱动程序来提高系统的可靠性和服务能力。 在本文中,将介绍新的存储保护机制,以及如何利用存储保护键来提高现有设备驱动程序,或内核扩展的可靠性、可用性和服务能力 (ras) 特征。
存储保护键
power6 处理器和 aix version 6.1 引入了一些新的功能,包括存储保护键以及 aix 内核对它们的支持。在本文中,存储保护键也称为存储键,或者键。键 为虚拟内存页面提供了上下文相关存储保护机制。软件可以使用键来分别保护多种数据种类,并在各个上下文的基础上控制对数据的访问。这与以前的页面保护机制是不同的,以前的页面保护机制从本质上说是全局的。
在内核模式和用户模式应用程序二进制接口 (abi) 中,都可以使用存储键。在内核模式的 abi 中,将存储键支持称为内核键。在用户空间中,将存储键称为用户键。内核扩展本身必须关注这两种类型的键。
内存保护域通常使用多个存储保护键,以实现额外的保护。aix version 6.1 将系统划分为四个内存保护域:
公共内核 可供使用(不仅限于内核及其扩展)的内核数据,如堆栈段、bss 段、数据段,以及从内核或者固定的存储堆中分配的区域。 私有内核 aix 内核中基本上私有的数据,如表示一个进程的相关结构。 内核扩展 主要由内核扩展使用的数据,如文件系统的 buf 结构。 用户 应用程序地址空间中的数据,可能使用键保护来控制对它自己的数据的访问。
这些不同域(除了公共内核之外)的一个目的是,保护一个域中的数据不受另一个域中编码错误的影响。在一定的程度上,您还可以保护一个域内的数据不受该域中其他子组件的影响。在内核扩展中编写存储保护功能时,您可以实现下面的部分,或者所有 ras 优势:
保护用户空间中的数据,以避免被您的扩展意外地覆盖。
考虑在应用程序中使用私有用户键保护,以保护它自己的私有数据。
保护内核私有数据,以避免被您的扩展意外地覆盖。
保护您的私有内核扩展数据,以避免被内核、其他内核扩展,甚至您自己的内核扩展的子组件意外地覆盖。
存储保护键不应该作为一种安全机制使用。应该遵循一组自愿的协议来使用键,而协作子系统设计人员根据这些协议可以更好地检测各种编程错误,并随后对其进行纠正。
存储键保护的程度
内核扩展可能在不同的程度上支持存储保护键,这取决于其独特的需求。这些程度包括:
键不安全的内核扩展 键不安全的内核扩展不包含任何对存储保护键的显式支持。这种类型中的扩展是遗留 代码(过去编写的代码,没有考虑到存储键保护),它需要对所有内存进行无限制访问。
内核的职责是,确保遗留代码继续工作(就像在以前的 aix 发行版中,以及没有提供存储键支持的硬件中一样地工作),即使这样的代码可能会访问内核私有数据。
键安全的内核扩展 键安全的内核扩展可以根据内核和用户域的边界,管理对内存的访问。它并不直接引用内核私有数据结构或者用户空间地址。要成为键安全的,扩展必须明确地选择它想要访问的现有内存域。这将保护系统的其余部分不受键安全模块中错误的影响。 键保护的内核扩展 键保护的内核扩展超出了键安全的范围;它标识并保护它自己的私有数据,以及其他域中的数据,以避免意外地访问。可以通过使用私有内核键、或者利用您已经使用的共享键,来完成这个任务。
键安全和键保护的内核扩展统称为可以识别键的 内核扩展。要使得一个内核扩展成为可以识别键的内核扩展,您必须了解键在内核中的使用情况。要使得一个内核扩展成为键保护的内核扩展,您还必须定义它的私有或者半私有数据,以及它如何使用键来保护这些数据。半私有键可能用于在几个相关的内核扩展中共享数据,而私有键则由单个扩展独自使用。
硬件体系结构
从 power6 处理器开始,支持使用键来实现硬件存储保护。这种硬件体系结构添加了两项新的内容:
每个虚拟内存页面都具有一个与其相关联的存储保护键。这个键是从 0 到 31 之间的一个整数,31 是所设计的最大值,当前各种计算机中的最大值都比这个最大值要小。
每个处理器都具有一个 64 位的权限屏蔽寄存器(authority mask register,amr)。amr 由 32 对二进制位组成,每对二进制位对应于一个存储保护键。每对二进制位包含一个读取访问位和一个写入访问位,用以确定该处理器是否可以读取、或者写入使用关联的存储保护键进行保护的某些虚拟内存页面。
如果一个程序在执行,对于与正在引用的数据相关联的键,amr 中不包含足够的权限,那么将出现数据存储中断(data storage interrupt,dsi)异常。
只有很少的几个硬件键可以使用。内核提供了一种称为内核键的抽象,它映射到多对一的硬件键。有限的硬件键数目意味着,关于数据的、某些程度的错误共享 是不可避免的。因为许多内核键可能映射到同一个硬件键,所以这些内核键的用户之间没有提供相应的保护。
键不安全的内核扩展支持
为了继续在键保护的环境中运行,内核对一些遗留的内核扩展提供了特殊的支持。所有经过转换以使用键的扩展仍然处于可识别键的和键不安全的函数的混合环境中。可识别键的内核扩展可能调用键不安全的内核扩展中的服务。
当调用一个键不安全的函数时,事实上,内核必须在调用栈中(在调用函数和被调用的键不安全的函数之间)透明地插入特殊的粘合代码。虽然这个操作是自动完成的,但是我们需要了解相应的机制,因为所插入的粘合代码在进行堆栈回调跟踪时是可见的。
在调用遗留代码的时候,可以通过调用导出的函数进行直接地调用,也可以通过使用函数指针进行间接地调用,但是内核必须完成以下工作:
保存调用者的当前键访问权限(保存于 amr 中)。
保存调用者的连接寄存器 (lr)。
使用授予广泛数据访问权限的值取代当前的 amr 值。
继续调用键不安全的函数,使用所设置的连接寄存器,以便被调用的函数返回下面的下一个步骤。
恢复原始调用者的 amr 和 lr 的值。
如果喜欢使用了存储键请收藏或告诉您的好朋友.
阅读(226) | 评论(0) | 转发(0) |