|
我们只解释一下最后一个case,即当a、b的类型均为MAC_MLS_TYPE_LEVEL时,也就是它们都使用一个数(0到254)标识它们的安全级时,判断是如何进行的。首先:
#define MAC_MLS_BIT_TEST(b, w) ((w)[(((b) - 1) >> 3)] & (1 << (((b) - 1) & 7)))
我们可以看到,在比较二者安全级之前,对它们的mme_compartments进行了位测试。mme_compartments是一个256bit的数据(由uchar[32]数组定义),每个bit都可以设置为1来表示该对象属于某一个安全域,当然也可以设置多个bit表示这个对象属于多个安全域。MLS要求如果a可以访问b的话,b所属的安全域必须要是a的子集,否则访问被拒绝。对mme_compartments进行测试的目的也即是要判断b中设置了1的那些bit在a中有否设置。
2.6 对MAC框架及MLS策略的扩充
最后我们对MAC框架作一点改进。前面提过,MAC框架目前并不支持对用户的安全级进行设置,也没有提供存储用户安全级信息的地方,我们想对之做改进,以使其更实用。我们改进的思想是,拦截系统的setuid系统调用,在系统作setuid的时候(用户登录、运行su命令等),读入用户安全级别信息并作相应设置。我们做了如下工作:
- 在mac_policy.h文件中的mac_policy_ops结构中增加一个新函数mpo_get_cred_from_file(),其参数和返回值与mpo_create_cred()完全一样。
- 在mac_mls.c文件中增加一个新函数mac_mls_get_cred_from_file(),其参数和返回值与mac_mls_create_cred()完全一样。在这个函数里,增加在内核中读写用户安全级配置文件的语句,从而把用户的安全级在这里读到标记中。然后在对mac_policy_ops结构的设置语句中,增加一条语句:.mpo_get_cred_from_file = mac_mls_get_cred_from_file。
- 在kern_prot.c文件中的setuid()函数里crcopy()函数替换为我们自己的mac_crcopy()函数,并在调用这个函数之前加一条语句:newcred->cr_uid = uid;。
- mac_crcopy()函数的代码如下:
void mac_crcopy(struct ucred *dest,struct ucred *src)
{
uid_t uid = dest->cr_uid;
KASSERT(crshared(dest) == 0,("crcopy of shared ucred"));
bcopy(&src->cr_startcopy,&dest->cr_startcopy,
(unsigned)((caddr_t)&src->cr_endcopy -
(caddr_t)&src->cr_startcopy));
uihold(dest->cr_uidinfo);
uihold(dest->cr_ruidinfo);
if(jailed(dest))
prison_hold(dest->cr_prison);
#ifdef MAC
dest->cr_uid = uid;
mac_get_cred(src,dest);
dest->cr_uid = src->cr_uid;
#endif
}
|
- 修改相应的头文件,并重新编译内核。
2.7 小结
上面分析了MAC框架与MLS策略的主要内容,限于篇幅,我们只给出主要逻辑,如果您想要了解更为详细的技术细节,请阅读其源代码或联系我。另外,MAC框架和MLS策略还用到了一些很重要的技术,如系统控制(sysctl)机制、锁等,我们也没有提到,如有兴趣的读者可以继续钻研。
上一页 [1] [2] [3]
|