Re: [PATCH bpf-next v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
David Windsor <[email protected]> Mon, 22 Jun 2026 23:49:14 -0400
| Newsgroups | org.kernel.vger.linux-integrity,org.kernel.vger.bpf,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-kselftest,org.kernel.vger.linux-security-module,org.kernel.vger.selinux |
|---|---|
| Message-ID | <CAEXv5_jVXS4JoExcd71YkXEE2WXPJ0_9STO-uCwgNF+Eia_h5w@mail.gmail.com> |
On Mon, Jun 22, 2026 at 7:57 PM Alexei Starovoitov <[email protected]> wrote: > > On Thu Jun 18, 2026 at 1:34 PM PDT, David Windsor wrote: > > + > > +static int __bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx, > > + const char *name__str, > > + const struct bpf_dynptr *value_p) > > +{ > > + struct bpf_dynptr_kern *value_ptr = (struct bpf_dynptr_kern *)value_p; > > + size_t name_len; > > + void *xattr_value; > > + struct xattr *xattr; > > + struct xattr *xattrs; > > + int *xattr_count; > > + const void *value; > > + u32 value_len; > > + > > + if (!xattr_ctx || !name__str) > > + return -EINVAL; > > + > > + xattrs = xattr_ctx->xattrs; > > + xattr_count = xattr_ctx->xattr_count; > > + if (!xattrs || !xattr_count) > > + return -EINVAL; > > + if (bpf_xattrs_used(xattr_ctx) >= BPF_LSM_INODE_INIT_XATTRS) > > + return -ENOSPC; > > This check is good to have, but it's enough. No need to duplicate it. > More below. > > > + > > static int bpf_fs_kfuncs_filter(const struct bpf_prog *prog, u32 kfunc_id) > > { > > if (!btf_id_set8_contains(&bpf_fs_kfunc_set_ids, kfunc_id) || > > - prog->type == BPF_PROG_TYPE_LSM) > > + prog->type == BPF_PROG_TYPE_LSM) { > > + /* bpf_init_inode_xattr only attaches to inode_init_security. */ > > + if (kfunc_id == bpf_init_inode_xattr_btf_ids[0] && > > + prog->aux->attach_btf_id != bpf_lsm_inode_init_security_btf_ids[0]) > > + return -EACCES; > > This is unnecessary. Only one hook will have xattr_ctx type. > The normal verifier type enforcement will do its work. > Good point, thanks. > > diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c > > index 1a721fc4bef5..b41b02173e24 100644 > > --- a/kernel/bpf/trampoline.c > > +++ b/kernel/bpf/trampoline.c > > @@ -859,6 +859,9 @@ static int bpf_trampoline_add_prog(struct bpf_trampoline *tr, > > } > > if (cnt >= BPF_MAX_TRAMP_LINKS) > > return -E2BIG; > > + if (node->link->prog->aux->attach_limit && > > + tr->progs_cnt[kind] >= node->link->prog->aux->attach_limit) > > + return -E2BIG; > > No need. The check inside kfunc is enough. > Paul wanted this check because it occurs at bpf prog attach time, whereas the one in the kfunc is at inode creation time. > > if (!hlist_unhashed(&node->tramp_hlist)) > > /* prog already linked */ > > return -EBUSY; > > diff --git a/security/bpf/hooks.c b/security/bpf/hooks.c > > index 40efde233f3a..d7c44c5c0e30 100644 > > --- a/security/bpf/hooks.c > > +++ b/security/bpf/hooks.c > > @@ -30,6 +30,7 @@ static int __init bpf_lsm_init(void) > > > > struct lsm_blob_sizes bpf_lsm_blob_sizes __ro_after_init = { > > .lbs_inode = sizeof(struct bpf_storage_blob), > > + .lbs_xattr_count = BPF_LSM_INODE_INIT_XATTRS, > > }; > > > > DEFINE_LSM(bpf) = { > > diff --git a/security/integrity/evm/evm_main.c b/security/integrity/evm/evm_main.c > > index b59e3f121b8a..e0a05162accc 100644 > > --- a/security/integrity/evm/evm_main.c > > +++ b/security/integrity/evm/evm_main.c > > @@ -1062,14 +1062,16 @@ static int evm_inode_copy_up_xattr(struct dentry *src, const char *name) > > * evm_inode_init_security - initializes security.evm HMAC value > > */ > > int evm_inode_init_security(struct inode *inode, struct inode *dir, > > - const struct qstr *qstr, struct xattr *xattrs, > > - int *xattr_count) > > + const struct qstr *qstr, > > + struct xattr_ctx *xattr_ctx) > > the rest looks good. > Pls split the patch. Introduce xattr_ctx first across the LSMs. > Then another patch with a new kfunc. > > pw-bot: cr