SELinu访问控制原理

zuoyudan 贡献于2015-03-21

作者 wolf  创建于2015-01-15 16:43:00   修改者wolf  修改于2003-01-20 02:45:26字数2883

文档摘要:一、SELinux访问控制原理SELinu主要的访问控制方式可分为下面几步:获取主体和客体的安全标识符(sid),SELinux在objsec.h文件中定义了各种对象的安全域,如下图所示,进程、索引节点、文件等都有对应的安全域,在安全域中以唯一的sid进行标识。获得主体和客体安全标识符后,根据两个sid以及目标类型就可以从访问向量缓存(AVC)中查找;
关键词:

 一、SELinux访问控制原理 SELinu主要的访问控制方式可分为下面几步: 1) 获取主体和客体的安全标识符(sid),SELinux在objsec.h文件中定义了各种对象的安全域,如下图所示,进程、索引节点、文件等都有对应的安全域,在安全域中以唯一的sid进行标识。 2) 获得主体和客体安全标识符后,根据两个sid以及目标类型就可以从访问向量缓存(AVC)中查找; 2.1 如果命中,则可以获取访问策略; 第 页 共 6 页 2.2 否则由安全策略服务器从策略库中查找,并将结果加入到AVC中。 3) 根据获得的决策(avd)与请求的权限进行比较,从而决定是否授权。 3 根据avd和所请求权限决定是否授权 2.2 Avc查找命中,获取avd 2.1Avc查找未命中,安全服务器计算出avd,并加入到avc中 2 在avc中查找 二、安全标识符表(sidtab) 在SELinux中,所有客体(文件、进程间通讯通道、套接字、网络主机等)和主体(进程)都有与其关联的安全上下文,一个安全上下文主要由三部分组成:用户、角色和类型标识符。因为SELinux的主要访问控制特性是类型强制(TE),安全上下文中的类型标识符决定了访问权。每个安全上下文都对应着有一个安全标识符sid。 struct context { u32 user; u32 role; u32 type; u32 len; /* length of string in bytes */ struct mls_range range; char *str; /* string representation if context cannot be mapped. */ }; 在安全服务器中有一个安全标识符表(sidtab),该表维护这sid和context的对应关系。 第 页 共 6 页 struct sidtab_node { u32 sid; /* security identifier */ struct context context; /* security context structure */ struct sidtab_node *next; }; 三、 AVC 下面是SELinux中的一个hook函数。 static int selinux_ptrace_traceme(struct task_struct *parent) { int rc; rc = cap_ptrace_traceme(parent); if (rc) return rc; return task_has_perm(parent, current, PROCESS__PTRACE); } /* * Check permission between a pair of tasks, e.g. signal checks, * fork check, ptrace check, etc. * tsk1 is the actor and tsk2 is the target * - this uses the default subjective creds of tsk1 */ static int task_has_perm(const struct task_struct *tsk1, const struct task_struct *tsk2, u32 perms) { const struct task_security_struct *__tsec1, *__tsec2; u32 sid1, sid2; rcu_read_lock(); __tsec1 = __task_cred(tsk1)->security; sid1 = __tsec1->sid; __tsec2 = __task_cred(tsk2)->security; sid2 = __tsec2->sid; rcu_read_unlock(); return avc_has_perm(sid1, sid2, SECCLASS_PROCESS, perms, NULL); } 第 页 共 6 页 以SELinux中的一个hook函数为例,task_has_perm()检查两个进程之间的权限问题,首先获取进程对应SELinux中的安全域中的sid,根据sid就可以获取访问策略。获取访问策略时首先在AVC中查找,如果找到则直接返回;否则则由安全服务器在安全策略中查找,并将结果插入到AVC中。 AVC提供了从安全服务器获得的访问策略的缓冲区,提高了安全机制的运行性能。它提供了hook函数高效检查授权的接口。 struct avc_entry { u32 ssid; u32 tsid; u16 tclass; struct av_decision avd; }; * @ssid: source security identifier * @tsid: target security identifier * @tclass: target security class * @requested: requested permissions, interpreted based on @tclass * @auditdata: auxiliary audit data int avc_has_perm(u32 ssid, u32 tsid, u16 tclass, u32 requested, struct common_audit_data *auditdata) { struct av_decision avd; int rc, rc2; rc = avc_has_perm_noaudit(ssid, tsid, tclass, requested, 0, &avd); //如果决策否决了操作,则将安全上下文、决策信息等写入log文件或输出 rc2 = avc_audit(ssid, tsid, tclass, requested, &avd, rc, auditdata); if (rc2) return rc2; return rc; } 该函数的功能是检查权限并执行合适的统计检查。该函数检查AVC来决定对应的一对安全标识符(ssid和tsid)是否被授予请求的权限。 inline int avc_has_perm_noaudit(u32 ssid, u32 tsid, u16 tclass, u32 requested, unsigned flags, struct av_decision *avd) { struct avc_node *node; 第 页 共 6 页 int rc = 0; u32 denied; BUG_ON(!requested); rcu_read_lock(); node = avc_lookup(ssid, tsid, tclass); if (unlikely(!node)) { node = avc_compute_av(ssid, tsid, tclass, avd); } else { memcpy(avd, &node->ae.avd, sizeof(*avd)); avd = &node->ae.avd; } denied = requested & ~(avd->allowed); if (unlikely(denied)) rc = avc_denied(ssid, tsid, tclass, requested, flags, avd); rcu_read_unlock(); return rc; } 该函数进行权限检查但不执行审计。首先加上读保护锁,接着调用avc_lookup()查询AVC缓冲向量,如果为空,则调用avc_compute_av(),该函数通过安全服务器获得决策avd,并把查询的结果加入到AVC缓冲区中。否则,将查询到的策略决策保存到avd中,并检查权限是否得到允许。 第 页 共 6 页

下载文档到电脑,查找使用更方便

文档的实际排版效果,会与网站的显示效果略有不同!!

需要 6 金币 [ 分享文档获得金币 ] 0 人已下载

下载文档