4.security_load_policy()
security_load_policy()函数用于加载一套新的安全策略,并使其生效,然后刷新访问向量缓存,并在必要的情况下转换SID表。其函数如下所示:
int security_load_policy(void*data, size_t len)
该函数包含两个参数:data表示二进制形式的策略数据;len表示策略数据的长度。对于该函数,其函数调用流程图如图2-14所示:下面结合源码对该函数的主要执行步骤进行说明:
① 判断ss_initialized变量是否设置,如果没有设置,表示安全服务器还没有进行初始化,此时按如下步骤进行处理:
a. 调用avtab_cache_init()函数对访问向量节点进行初始化。
b. 调用policydb_read()函数代表策略库的二进制文件中读取配置数据到策略库结构体中。
c. 调用selinux_set_mapping()函数计算seclass_map中客体类别的数量,并将seclass_map中字符形式的类别-权限映射转换为数值形式的类别权限映射。
d. 调用policydb_load_isids()函数将策略库中的初始SID加载到SID表中。
e. 调用security_load_policycaps()函数对策略所具有的能力进行初始化。
f. 调用selinux_complete_init()函数在策略载入之前对超级块进行设置。
g. 调用avc_ss_reset()函数来刷新AVC,并且是相应的权限重新生效。
h. 调用selinux_status_update_policyload()函数来修改策略重载的事件。
i. 调用selinux_netlbl_cache_invalidate()函数来使网络标记缓存无效。
j. 结束并返回。
② 调用policydb_read()函数代表策略库的二进制文件中读取配置数据到策略库结构体中。

图2-14security_load_policy()函数调用流程图
① 判断原有的策略库和新载入的策略库是否支持MLS。如果两者类型不一样,则记录MLS的状态。
② 调用policydb_load_isids()函数将策略库中的初始SID加载到SID表中,如果函数执行失败,则调用policydb_destroy()函数释放为策略库数据结构申请的内存空间,然后直接返回。
③ 调用selinux_set_mapping()函数计算seclass_map中客体类别的数量,并将seclass_map中字符形式的类别-权限映射转换为数值形式的类别权限映射,如果函数执行失败,则释放相应的存储空间并返回。
④ 调用security_preserve_bools()函数根据策略库中的布尔值对条件策略中的规则进行处理,并将相应的规则放入相应的链表中。
⑤ 调用sidtab_map()函数来将复制旧的sid表到newsidtab中。
⑥ 调用sidtab_map()函数来将newsidtab中其中的相应sid对应的安全上下文的值从旧策略中指定的值转换为新策略指定的值,并在新策略中确定相应的安全上下文的有效性。
⑦ 安装新的策略和SID表。
⑧ 调用policydb_destroy()、sidtab_destroy()和kfree()函数来分别释放旧的策略库、旧的SID表以及旧的映射关系。
⑨ 调用avc_ss_reset()函数来刷新AVC,并且是相应的权限重新生效。
⑩ 调用selinux_status_update_policyload()函数来修改策略重载的事件。
11 调用selinux_netlbl_cache_invalidate()函数来使网络标记缓存无效
12 结束并返回。
5.convert_context()
当调用security_load_policy()函数加载了一个新的策略之后,就需要对客体的安全上下文进行修改。在Linux中,通过convert_context()函数来实现该功能,convert_context()函数将安全上下文c中的值由p->oldp指定的值转化为p->newp指定的值,并基于新策略确定安全上下文的有效性。其函数头如下所示:
static int convert_context(u32 key,struct context *c,void *p)
该函数包含3个参数:key表示待转换的安全上下文对应的SID;c表示待转换的安全上下文;p表示策略载入前后所使用的策略库。下面对该函数的主要执行步骤进行说明:
① 判断key是否小于等于SECINITSID_NUM,如果是,表示该SID为初始SID,函数直接返回。
② 判断待转换的安全上下文的字符串表示形式是否存在。若存在,则先复制该字符串,接着调用string_to_context_struct()函数将该字符串转化为相应的context结构体,最后根据string_to_context_struct()函数进行不同的处理,并返回。
③ 调用context_cpy()函数复制待转换的安全上下文到oldc中。
④ 调用hashtab_search()函数从新策略的用户符号表中查找待转换的安全上下文在旧策略中的用户符号串对应的安全属性,然后根据相应的值设置待转换的安全上下文c中的用户标识。
⑤ 使用同用户转换同样的方法来实现角色、类型、MLS域的转换。对于MLS域的转换根据新旧策略是否启动了MLS进行不同的处理。
⑥ policydb_context_isvalid()函数根据新策略判断安全上下文的有效性。如果某个域无效,则调用convert_context_handle_invaild_context()函数对待转换的安全上下文进行处理。
⑦ 调用context_destroy()函数释放oldc所占有的空间。
⑧ 结束并返回。返回搜狐,查看更多