LSM零知识学习五、插桩原理实现细节(3)

接前一篇文章: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__);

实际上是声明了一个函数指针。那么这个函数指针指向了谁呢?又是什么时候被赋值的呢?

且看下回分解。

猜你喜欢

转载自blog.csdn.net/phmatthaus/article/details/131102166