虚拟机中关于内存保护的故障隔离技术研究
- 格式:pdf
- 大小:279.47 KB
- 文档页数:4
第29卷第16期
VO1.29 NO.16 计算机工程与设计
Computer Engineering and Design 2008年8月
Aug.2008
虚拟机中关于内存保护的故障隔离技术研究
王小光, 夏克俭, 张焕生
(北京科技大学信息工程学院计算机系,北京100083)
摘要:讨论了虚拟机中如何实现内存保护的技术并对其进行研究。在相互协作的软件模块中提供故障隔离的一种方法是 将各个软件模块放在他自己的地址空间中,然而在高度耦合的模块中,这无疑会导致上下丈切换的时间开销,为了在虚拟
机中解决这一问题,最终给出了一个软件方法使得故障隔离在单一的地址空间就可以实现。试验结果表明,这是一个高效
的基于软件的内存保护技术,并且该技术已经成功应用在了一个实际的虚拟机中。
关键词:内存保护:故障隔离;沙箱:段匹配;虚拟机 中图法分类号:TP3l9 文献标识码:A 文章编号:1000—7024(2008)16—4315—04
Research for fault isolation of memory protection in virtual machines
WANG Xiao—guang,XIA Ke-jian,ZHANG Huan—sheng
(Department of Computer,School of Information Engineering,University of Science and Technology Beijing,
Beijing 100083,China)
Abstract:A research ofmemory protection technology and how to implement are discussed.One way to provide fault isolation among cooperating software modules is to place each in its own address space.However,for tightly—coupled modules,this method would be
lead to context switch overhead.To solve this problem in VM,a technology is introduled,which present a software approach to imple— menting fault isolation within a single address space.It is to be checked that this method is efficient software—based fault isolation,and this technology have been successfully used in an actual virtual machines.
Key words:memory protection;fault isolation;sandbox;segment matching;virtual machine
0引 言
给定一个地址空间的映射及其实现方法,有几个内存体
系结构中的特性必须在虚拟机中得到仿真。尤其是ABI(ap. plicationbinaryinterface)内存体系结构也就是用户级应用所看
到的内存的3个特性必须要考虑: (1)地址空间的全局结构。例如是否被划分成段结构还是
整个的线性地址空间。我们的大部分讨论均局限在线性地址 空问中,因为大多数流行的ABI都使用线性地址空间(尽管可
能被进一步的划分为堆和栈)。而且在这些线性地址空间中
可以建立虚拟的段内存技术。 (2)支持的访问权限类型。一些AB1支持读,写,执行(R,
w,E)权限,还有的被限制为只支持读,写。
(3)保护和分配粒度。就是说操作系统可以分配的内存块 的最小尺寸和所能持有的最小的保护粒度的内存大小。在大 多数系统中内存分配和保护的粒度是相同的,然而,严格的 说,他们也不必相同。
个应用程序通常可以有可扩展的特性,而这种特性是
通过由独立开发的软件模块的相互协作达成的。然而在这些 可以扩展的代码中如果存在故障代码,这将使得这个软件系 统不再可靠,甚至是危险的,例如这个故障代码可以摧毁永久
数据。为了增加可扩展软件的可靠性,操作系统可以提供服 务,从而阻止不可信模块中的故障代码破坏应用程序数据,这
种故障隔离服务通过确认原系统的错误使得软件开发变的更
加方便。 本文介绍的如何降低故障隔离技术的执行成本,使得系
统模块开发者在选择哪个模块放入彼此分开的故障域时可以 忽略他的效能影响。在很多场合下故障隔离技术都是很有用
的,比如跨域的函数调用十分频繁而每个调用又包含合理的
开销。由于跨越硬件边界的开销,将逻辑上独立的模块再分 配到各自的地址空间就是不切实际的。 本文只论述简单的交换技术,称为沙箱技术,这个技术以
轻微增加了执行被修改的对象代码的时间为代价。
1虚拟机的内存保护的研究
我们这里仅讨论运行时内存的保护问题。由于运行时软 件(包括运行时的代码和数据)和客户应用软件共享一个地址
空间,所以运行时必须受到来自客户应用的保护。例如如果
收稿日期:2007—09.05 E-mail:individual2499@163.corn 作者简介:王小光(1976--),男,内蒙古人,硕士研究生,研究方向为计算机软件与理论; 夏克俭(1955--),男,湖北人,教授,研究方向为 计算机软件、智能管理、数据库技术; 张焕生(1978一),女,河北人,硕士研究生,研究方向计算机软件与理论。
维普资讯 http://www.cqvip.com 一个仿真程序由于错误试图访问一个属于运行时的地址区域,
那么这就应该被报告成一个关于仿真应用的内存错误。为维 持兼容性和给出正确结果考虑,客户程序不应被允许读写运 行时的内存区域。
一个高效的解决方案被利用在了Omniware VM虚拟机
(Lucco,Sharp,and Wahbe 1995:Wahbe et a1.1993)中,在这个系统
中,利用宿主硬件来支持地址转换,但保护验证仍由软件实 现。为流线化软件的保护验证,客户的数据和代码被划分成
2的幂次方大小的段,通过依赖这样的段划分,只需单一的移
位(提取出段的地址位)和比较就可以高效的完成验证工作。 在任何时候如果只有一个数据段是活动的,那么当前可访问
的段的地址位就可以存入宿主机的寄存器中,也就使得比较
操作更加迅速。进一步的,通过分析程序控制流,类似在HLL 虚拟机中采用的可以减少空指针和数组范围检查的优化也能
被应用。这能减少更多的时间开销,大概是整体的l0%(有时 会更少)。尽管这个技术保护了运行时免遭客户的越界访问,
然而强制的2的幂次方大小的段可能减弱实质的兼容性,因
为放在内存地址空间的这些限制是本地平台所没有的。
一种采用底层硬件实现的既有地址转换又有保护验证的
技术可以在Dynamo系统(Bala,Duestewald,andBanerjia2000)看 到。用这种方法,运行时系统负责调用恰当的宿主操作系统
的例程来设置内存保护。这时会有两种执行模式。在仿真模
式下,被转换了的客户代码正在执行;其余的所有时间,包括 二进制转换器生成代码的时间,虚拟机都在运行时模式下执
行。只有当虚拟机在仿真模式下,运行时的代码和数据必须
被转换后的代码保护。从而在这两种模式下的内存保护将是 不同的,如图1所示。
运行时模式
运行时数据
运行时代码
代码Cache
客户数据
客户代码 N N
R,W N
Ex N
R,W Ex
N N
R,W R,W
R R 仿真模式 薯 3 t
运行时数据
运行时代码
代码Cache
蠢 玺 ∞
客户数据
客户代码
图1利用缓存的转换代码进行内存保护设置
图1描述了在运行时模式和仿真模式下的内存保护。在 运行时模式时,运行时代码是可执行的;运行时的数据结构都
是读写可访问的,代码缓存Cache是可读写的,这是因为它必
须在转换过程中被访问和修改。在仿真模式下,所有的运行 时数据结构都变成了不可访问的,并且此时代码缓存Cache也
只是可执行的了:只有在客户的内存映像中的数据是可以
访问的。 要改变这种基于执行模式的保护,运行时可以利用一个
系统调用,比如Linux可以用mpr0tect0调用,来改变运行时的
一4316一 数据和代码为不可访问的并且代码缓存Cache为只执行的。
当然,对于模式的切换也可以类似的执行。当控制返回到运
行时时,它能重新建立读写权限。这也留下了仿真软件企图 跳转到或者分支到运行时区域的问题。这个可以在解释阶段
或者二进制翻译阶段被检查出来。在解释阶段期间,分支和 跳转的目的可以被解释器精确的检查出来。对于已经转换了
的代码,代码块中的所有分支和跳转将在代码块内部直接寻
址。而代码块中的所有非直接跳转和分支通过同在该块中的 映射表或者连接指针进行相应操作。所有这些都是通过运行
时写入的,并且可以在写入的时候验证地址。 这种方法是有效的,不过当有模式切换时会有相对高的
时间开销。然而如果代码缓存的效率足够高(通常是这样的),
客户的指令工作集被翻译转换后,这个开销是可以忽略的。
2软件实施的故障隔离技术的研究
在这个部分,我们列出几个软件封装技术,从而将不可信 模块限制在他自己的故障区域里。我们首先介绍一种允许用
户在软件模块中定位错误的技术,然后我们介绍一种称为沙
箱的技术——只需以微小的增加执行时间为代价既可以隔离 不可信模块。最后我们给出一个软件封装技术,使得相互协
作关联的故障区域可以共享内存。在这部分的讨论中我们利 用RISC装载/存储体系结构,当然这个技术也适用于CISC。
第4部分描述如何提高跨故障区域RPC的效能和安全的实现。 我们将一个应用程序的虚拟地址空间划分成若干的段,
一个段中的所有虚拟地址是对齐的,即共享一个惟一的高位
地址模式,称为段标志符。一个故障域包含两个段,一个用于 存放不可信模块的代码,另一个用于存放他的静态数据和堆
栈。具体的段地址在加载时确定。
软件封装技术既是改变一个不可信代码模块的对象代 码,使得他只能在他自身的代码段中跳转到相应的目标地址,
并且只能在他的数据段中的相应地址进行写入。因此,在不
可信模块中的所有合法跳转目标地址都有一个相同的高位模 式(段标志符):类似的,由不可信模块产生的所有合法的数据
地址也共享相同的段标志符。为了避免模块修改他的代码段, 将代码段和数据段分开是必要的。对于一个含有正确段标志
符的地址也可能是非法的,比如这个地址如果参考一个非映 射页面,这种异常会被操作系统的缺页中断机制捕获。
2.1段匹配
一个不安全指令是这样的一个指令,他跳转的或存储的 地址不能被静态地验证是否在正确的段中。大多数控制转移
指令,比如相对于程序计数器的分支指令,能被静态的验证。
利用立即寻址模式的静态变量存储指令也是能被静态验证的。 然而,借助于寄存器的跳转指令,这些指令通常用于实现函数