Re: [PATCH RFC bpf-next 1/4] audit: Implement bpf_audit_log_*() wrappers
Kumar Kartikeya Dwivedi <[email protected]> Tue, 17 Mar 2026 03:04:51 +0100
| Newsgroups | org.kernel.vger.audit,org.kernel.vger.bpf,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-security-module |
|---|---|
| Message-ID | <CAP01T77mRSxLN_nZdgd-qv-u7i5SEiSU5azohVcc_NZdqHnqOw@mail.gmail.com> |
On Wed, 11 Mar 2026 at 22:31, Frederick Lawler <[email protected]> wrote: > > The primary use case is to provide LSM designers a direct API to report > access allow/denies through the audit subsystem similar to how LSM's > traditionally log their accesses. > > Left out from this API are functions that are potentially abuseable such as > audit_log_format() where users may fill any field=value pair. Instead, the > API mostly follows what is exposed through security/lsm_audit.c for > consistency with user space audit expectations. Further calls to functions > report once to avoid repeated-call abuse. > > Lastly, each audit record corresponds to the loaded BPF program's ID to > track which program reported the log entry. This helps remove > ambiguity in the event multiple programs are registered to the same > security hook. > > Exposed functions: > > bpf_audit_log_start() > bpf_audit_log_end() > bpf_audit_log_cause() > bpf_audit_log_cap() > bpf_audit_log_path() > bpf_audit_log_file() > bpf_audit_log_ioctl_op() > bpf_audit_log_dentry() > bpf_audit_log_inode() > bpf_audit_log_task() > bpf_audit_log_net_sock() > bpf_audit_log_net_sockaddr() > > Signed-off-by: Frederick Lawler <[email protected]> > --- > include/linux/lsm_audit.h | 1 + > include/uapi/linux/audit.h | 1 + > security/lsm_audit_kfuncs.c | 306 ++++++++++++++++++++++++++++++++++++++++++++ > 3 files changed, 308 insertions(+) > > diff --git a/include/linux/lsm_audit.h b/include/linux/lsm_audit.h > index 382c56a97bba1d0e5efe082553338229d541e267..859f51590de417ac246309eb75a760b8632224be 100644 > --- a/include/linux/lsm_audit.h > +++ b/include/linux/lsm_audit.h > @@ -78,6 +78,7 @@ struct common_audit_data { > #define LSM_AUDIT_DATA_NOTIFICATION 16 > #define LSM_AUDIT_DATA_ANONINODE 17 > #define LSM_AUDIT_DATA_NLMSGTYPE 18 > +#define LSM_AUDIT_DATA_CAUSE 19 /* unused */ > union { > struct path path; > struct dentry *dentry; > diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h > index 14a1c1fe013acecb12ea6bf81690965421baa7ff..7a22e214fe3e421decfc4109d2e6a3cee996fe51 100644 > --- a/include/uapi/linux/audit.h > +++ b/include/uapi/linux/audit.h > @@ -150,6 +150,7 @@ > #define AUDIT_LANDLOCK_DOMAIN 1424 /* Landlock domain status */ > #define AUDIT_MAC_TASK_CONTEXTS 1425 /* Multiple LSM task contexts */ > #define AUDIT_MAC_OBJ_CONTEXTS 1426 /* Multiple LSM objext contexts */ > +#define AUDIT_BPF_LSM_ACCESS 1427 /* LSM BPF MAC events */ > > #define AUDIT_FIRST_KERN_ANOM_MSG 1700 > #define AUDIT_LAST_KERN_ANOM_MSG 1799 > diff --git a/security/lsm_audit_kfuncs.c b/security/lsm_audit_kfuncs.c > new file mode 100644 > index 0000000000000000000000000000000000000000..0d4fb20be34a61db29aa2c48d2aefc39131e73bf > --- /dev/null > +++ b/security/lsm_audit_kfuncs.c > @@ -0,0 +1,306 @@ > +// SPDX-License-Identifier: GPL-2.0-only > +/* Copyright (c) 2026 Cloudflare */ > + > +#include <linux/audit.h> > +#include <linux/bpf_mem_alloc.h> > +#include <linux/gfp_types.h> > +#include <linux/in6.h> > +#include <linux/lsm_audit.h> > +#include <linux/socket.h> > +#include <linux/types.h> > + > +struct bpf_audit_context { > + struct audit_buffer *ab; > + u64 log_once_mask; > +}; > + > +static struct bpf_mem_alloc bpf_audit_context_ma; bpf_mem_alloc will be deprecated, please use kmalloc_nolock(). > + > +static inline u64 log_once(struct bpf_audit_context *ac, u64 mask) > +{ > + u64 set = (ac->log_once_mask & mask); > + > + ac->log_once_mask |= mask; > + return set; > +} > + > + [...] > + > +__bpf_kfunc int > +bpf_audit_log_net_sockaddr(struct bpf_audit_context *ac, int netif, > + const struct sockaddr *saddr__nullable, > + const struct sockaddr *daddr__nullable, int addrlen) > +{ > + struct lsm_network_audit net; > + struct common_audit_data ad; > + > + net.netif = netif; > + > + if (!saddr__nullable && !daddr__nullable) > + return -EINVAL; Code look a lot cleaner if you just stashed these locally in a better named variable. > + > + if (saddr__nullable && daddr__nullable && > + saddr__nullable->sa_family != daddr__nullable->sa_family) > + return -EINVAL; > + > [...] > + > +/* The following have a recursion opportunity if a LSM is attached to any of > + * the following functions, and a bpf_audit_log_*() is called. > + * security_current_getlsmprop_subj, > + * security_lsmprop_to_secctx, or > + * security_release_secctx > + */ > +BTF_ID_FLAGS(func, bpf_audit_log_cause, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_cap, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_path, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_file, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_ioctl_op, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_dentry, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_inode, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_task, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_net_sock, KF_DESTRUCTIVE); > +BTF_ID_FLAGS(func, bpf_audit_log_net_sockaddr, KF_DESTRUCTIVE); > + > +BTF_KFUNCS_END(lsm_audit_set_ids) > + > +static int bpf_lsm_audit_kfuncs_filter(const struct bpf_prog *prog, > + u32 kfunc_id) > +{ > + if (!btf_id_set8_contains(&lsm_audit_set_ids, kfunc_id)) > + return 0; > + > + return prog->type != BPF_PROG_TYPE_LSM ? -EACCES : 0; > +} > + > +static const struct btf_kfunc_id_set bpf_lsm_audit_set = { > + .owner = THIS_MODULE, > + .set = &lsm_audit_set_ids, > + .filter = bpf_lsm_audit_kfuncs_filter, > +}; > + > +static int lsm_audit_init_bpf(void) > +{ > + int ret; > + > + ret = bpf_mem_alloc_init(&bpf_audit_context_ma, > + sizeof(struct bpf_audit_context), false); One you switch to kmalloc_nolock you can drop this too. > + return ret ?: register_btf_kfunc_id_set(BPF_PROG_TYPE_LSM, > + &bpf_lsm_audit_set); > +} > + > +late_initcall(lsm_audit_init_bpf) > > -- > 2.43.0 > >