4.3.3 能力表的保护和权限的撤销
1.能力表的保护
对于访问控制矩阵来说,其行和列分别由主体和对象索引。访问控制矩阵通常是稀疏的,因为大多数对象对许多主体来说不能访问。所以,将矩阵分成更小、更容易处理的单元是合理的。一种可能是为每个主体分配访问矩阵的相应的行。给定一个主体,能力列表规定访问对象集和对访问对象的权限集。能力是对象代表,通常是名称或有权限的标识符。
如果主体拥有某一对象能力,那么该主体可以访问这一对象。能力本身就是被保护的对象,用户必须保护它们不被修改。有三种方法可以用于保护能力表:标签、受保护内存和加密技术。
(1)标签
标签式结构中有一个与每一个硬件字相关的比特集合。标签有set和unset两种状态。如果标签的状态是set,则普通进程就可以读这个字,但不能更改。如果标签状态是unset,则普通进程就可以读和修改。普通进程不能修改标签的状态,只有处于特权模式下的处理器才能进行修改。
例如:B5700系统使用了标签式结构。标签域包含三个比特,标示了这种结构如何使用这个字(指针、描述符、类型等)。
(2)受保护内存
使用与内存分页或分段相关联的保护比特。所有的能力表都存储在一个内存页面中,进程只能读取但不能改变这些内存。
例如:CAP系统不允许进程修改存放指令的内存分段,它也将能力表存放在这个分段。一个防护寄存器将指令与能力表隔开。
(3)加密技术
密码校验和是实现信息完整性检验的一种机制。每个能力表都有一个与之相关的密码校验和,该校验和由密码系统进行加密,而操作系统掌握密钥。当进程向操作系统提交能力表时,系统首先重新计算与能力表关联的密码校验和。然后,系统可以使用密钥加密该校验和,并且将结果与能力表中存储的校验和进行比较,或者解密能力表中的校验和,并与计算得出的校验和相比较。如果结果匹配,那么能力表没有被修改,否则,能力表被拒绝。
例如:Amoeba系统是一个使用能力表指定客体的分布式系统。在创建客体时,要返回一个与该客体关联的能力表。要使用客体时,程序要提交相关的能力表。能力表要编码客体的名字(24比特)、创建客体的服务器(48比特)和权限(8比特),共128比特。其中,最后的48比特作为校验域使用,它是能力表创建时选用的一个随机数。这个随机数存放在创建该客体的服务器的一个表中,当能力表提交给服务器时,服务器将验证这个随机数是否正确。攻击者如果想伪造能力表,就必须知道这个随机数。
2.能力表中权限的撤销
在能力表中,如果撤销对一个客体的访问权限,需要撤销所有对该客体授权的能力表。理论上,要求对每一个进程进行检查,删除相关能力表。但这种操作开销过大,所以要使用其他替代方法。
最简单的机制是间接客体引用。定义一个或多个全局客体表,在此模式下,每一个客体在表中有一对应的条目。能力表不直接指定客体的名字,而是指定客体在全局客体表中的条目。
该方法具有以下优点:要撤销客体权限,只需将该客体在全局客体表中的条目设为无效,这样所有对该客体的引用都将返回一条无效条目,访问被拒绝。如果只撤销客体的部分权限,该客体可以有多个条目,每一个条目对应不同的访问权限集或不同的用户组。
例如:Amoeba系统使用的就是这种方案。要撤销一个能力表,客体的拥有者请求服务器改变能力表的随机数,并发布新的能力表。这样可将现有的能力表置为无效。
另一种撤销权限的机制是使用抽象数据类型管理器。每一种抽象数据类型中都包含一个权限撤销子程序。当访问权限被撤销时,类型管理器只需禁止被收回权限的主体再次访问即可。这并不影响这种抽象数据类型的客体的其他访问方法。例如,一个文件的访问权限被撤销,这种方法不影响使用其他类型管理器对当前使用的分段进行访问。