为何Linux内核LSM_HOOK宏定义包含大量参数?
关于Linux内核中LSM_HOOK宏多参数的疑问
在Linux内核中,LSM_HOOK的使用示例如下:
LSM_HOOK(int, 0, binder_set_context_mgr, const struct cred *mgr) LSM_HOOK(int, 0, binder_transaction, const struct cred *from, const struct cred *to) LSM_HOOK(int, 0, binder_transfer_binder, const struct cred *from, const struct cred *to) LSM_HOOK(int, 0, binder_transfer_file, const struct cred *from, const struct cred *to, struct file *file) LSM_HOOK(int, 0, ptrace_access_check, struct task_struct *child, unsigned int mode) LSM_HOOK(int, 0, ptrace_traceme, struct task_struct *parent) LSM_HOOK(int, 0, capget, struct task_struct *target, kernel_cap_t *effective, kernel_cap_t *inheritable, kernel_cap_t *permitted) LSM_HOOK(int, 0, capset, struct cred *new, const struct cred *old, const kernel_cap_t *effective, const kernel_cap_t *inheritable, const kernel_cap_t *permitted) LSM_HOOK(int, 0, capable, const struct cred *cred, struct user_namespace *ns, int cap, unsigned int opts)
而LSM_HOOK在定义struct security_hook_heads时的宏展开如下:
struct security_hook_heads { #define LSM_HOOK(RET, DEFAULT, NAME, ...) struct hlist_head NAME; #include "lsm_hook_defs.h" #undef LSM_HOOK } __randomize_layout;
可以看到,在这个场景下,除NAME外的其他参数都被丢弃了,想了解该宏为何需要定义这么多参数?
原因解析
统一宏定义的复用性:
LSM_HOOK宏并非仅用于定义struct security_hook_heads中的链表头。在内核其他代码逻辑中,这个宏会被重新定义,用来生成钩子函数的原型、默认实现、钩子调用逻辑等。比如在其他场景下,RET(返回值类型)、DEFAULT(默认返回值)和可变参数(函数参数列表)都会被实际使用,以此构建完整的钩子函数框架。维护单一的钩子定义源:内核将所有LSM钩子的定义集中放在
lsm_hook_defs.h中,通过同一个LSM_HOOK宏描述每个钩子的完整元信息(返回值、默认值、名称、参数)。不管是生成钩子链表头,还是生成钩子函数的声明、调用代码,都可以直接包含该头文件,通过重新定义LSM_HOOK宏实现不同的代码生成逻辑,避免重复编写钩子的元信息,降低维护成本。代码可读性与一致性:每个
LSM_HOOK调用都完整描述了对应钩子函数的签名,即便在生成链表头的场景下这些参数暂时未被使用,也能让开发者快速看懂该钩子的用途、参数和返回值,保持了代码的一致性和可读性。
内容的提问来源于stack exchange,提问作者Junhui Zhu
相关产品推荐
相关产品推荐

