接前一篇文章:LSM零知识学习四、插桩原理实现细节(2)
本文内容参考:
LSM(Linux Security Modules)框架原理解析_lsm linux_pwl999的博客-CSDN博客
特此致谢!
二、security_file_open函数上下文
fs/open.c中的vfs_open函数调用同文件中的do_dentry_open函数,do_dentry_open函数又调用了security_file_open函数(security/security.c中),最终在security_file_open函数中调用了call_int_hook函数。
int security_file_open(struct file *file)
{
int ret;
ret = call_int_hook(file_open, 0, file);
if (ret)
return ret;
return fsnotify_perm(file, MAY_OPEN);
}
前一篇文章详细解析了call_int_hook函数(准确地说是宏)中的hlist_for_each_entry(P, &security_hook_heads.FUNC, list),本文继续往下进行解析。再贴一下call_int_hook源码,在security/security.c中:
#define call_int_hook(FUNC, IRC, ...) ({ \
int RC = IRC; \
do { \
struct security_hook_list *P; \
\
hlist_for_each_entry(P, &security_hook_heads.FUNC, list) { \
RC = P->hook.FUNC(__VA_ARGS__); \
if (RC != 0) \
break; \
} \
} while (0); \
RC; \
})
实际展开call_int_hook(file_open, 0, file),最终为:
for (P = ({ struct hlist_node ____(&security_hook_heads.file_open)->first = ((&security_hook_heads.file_open)->first); ____(&security_hook_heads.file_open)->first ? container_of(____(&security_hook_heads.file_open)->first, struct security_hook_list, list) : NULL; }); \
P; \
P = ({ struct hlist_node ____(P)->list.next = ((P)->list.next); ____(P)->list.next ? container_of((P)->list.next), struct security_hook_list, list) : NULL; }) )
再来看看循环体中的内容:
RC = P->hook.FUNC(__VA_ARGS__);
if (RC != 0)
break;
前文已提到,P的类型为struct security_hook_list,其定义在include/linux/lsm_hooks.h中:
/*
* Security module hook list structure.
* For use with generic list macros for common operations.
*/
struct security_hook_list {
struct hlist_node list;
struct hlist_head *head;
union security_list_options hook;
const char *lsm;
} __randomize_layout;
其中成员变量hook的类型为union security_list_options,其在include/linux/lsm_hooks.h中定义:
union security_list_options {
#define LSM_HOOK(RET, DEFAULT, NAME, ...) RET (*NAME)(__VA_ARGS__);
#include "lsm_hook_defs.h"
#undef LSM_HOOK
};
lsm_hook_defs.h文件的内容上一篇文章已经给出过了,在此不再重复贴出。只给出file_open的相关内容:
LSM_HOOK(int, 0, file_open, struct file *file)
参照include/linux/lsm_hook_defs.h文件中的说明:
/*
* The macro LSM_HOOK is used to define the data structures required by
* the LSM framework using the pattern:
*
* LSM_HOOK(<return_type>, <default_value>, <hook_name>, args...)
*
* struct security_hook_heads {
* #define LSM_HOOK(RET, DEFAULT, NAME, ...) struct hlist_head NAME;
* #include <linux/lsm_hook_defs.h>
* #undef LSM_HOOK
* };
*/
可知,LSM_HOOK(int, 0, file_open, struct file *file)展开为以下内容:
int (*file_open)(__VA_ARGS__);
实际上是声明了一个函数指针。那么这个函数指针指向了谁呢?又是什么时候被赋值的呢?
且看下回分解。