在linux系统启动中:
start_kernel -> security_init,在此函数中:
1、struct hlist_head {
struct hlist_node *first;
};
将lsm的钩子函数集合security_hook_heads放到hlist_head 结构的 list链表中,有的钩子函数是特定框架才有的;
2、三种安全检查的初始化:
-> capability_add_hooks
1) 实现capability安全模块中的hook函数(函数定义)。
2) 用已实现的hook函数,初始化capability_hooks(结构体定义)。
struct security_hook_list capability_hooks[] __lsm_ro_after_init = {
LSM_HOOK_INIT(capable, cap_capable),
……
};
定义#define LSM_HOOK_INIT(HEAD, HOOK) \
{ .head = &security_hook_heads.HEAD, .hook = { .HEAD = HOOK } }
展开后:
.head = &security_hook_heads.capable, .hook = { .capable = cap_capable }
相当于在capability_hooks数组中,对其中一个security_hook_list类型对象做了初始化。
3) 将capability_hooks的所有成员变量list添加到成员变量head之前,组成一个链表(如果后续有其他安全模块,对capable函数增加其他的hook函数实现,新的hook实现又会被放到当前hook函数之前,类似于一个栈结构)。
-> yama_add_hooks
-> loadpin_add_hooks
3、do_security_initcalls
调用security_initcall_start 和security_initcall_end 之间的各个安全策略的初始化函数,如selinux、apparmor、smack 和 tomoyo。
security_initcall(selinux_init)
security_initcall(apparmor_init)
security_initcall(smack_init)
security_initcall(tomoyo_init)
485 #define SECURITY_INIT \
486 .security_initcall.init : AT(ADDR(.security_initcall.init) - LOAD_OFFSET) { \
487 security_initcall_start = .; \
488 KEEP(*(.security_initcall.init)) \
489 security_initcall_end = .; \
490 }