In Linux kernel, the LSM_HOOK
usage is like:
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)
The LSM_HOOK
is defined as:
struct security_hook_heads {
#define LSM_HOOK(RET, DEFAULT, NAME, ...) struct hlist_head NAME;
#include "lsm_hook_defs.h"
#undef LSM_HOOK
} __randomize_layout;
In this situation, parameters except for NAME
are all discarded. I am curious why the macro expansion needs so many arguments like above. Thanks!
This is because the macro
LSM_HOOK
has different implementations in various subsystem or modules, as you can see, in the struct, itundef
the macro immediately after usage, so in this particular module, the remaining arguments are not needed and ignored. But let's look at another module, e.g. inbpf_lsm.h
, it definesLSM_HOOK
like this:where the extra arguments are passed into the
bpf_lsm_...
functions. So this kind of macro provides extensibility and flexibility among different modules.