Re: [PATCH v3 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
David Windsor <[email protected]> Wed, 24 Jun 2026 17:22:54 -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_gSOoHnVn9bKsCdHB5aR_tNHRZ+m2trVcYNmbtS-K=4fQ@mail.gmail.com> |
On Tue, Jun 23, 2026 at 8:12 PM Paul Moore <[email protected]> wrote: > > I have a few specific comments below, inline with the patch, but I wanted > to make some general comments too. > > The kfunc additions really don't belong in the VFS kfunc file, please > create a LSM kfunc file (call it security/bpf_lsm_kfuncs.c) and add the > kfunc code to this new file. > Makes sense. I will also do similarly for the selftests. > While moving the kfunc additions to a LSM kfunc file does sort of convert > the VFS changes into LSM changes, Christian's comment about splitting > this patch two patches, one with the LSM hook changes and one with the > BPF additions, is still reasonable and a good suggestion. I would still > CC the VFS folks on these patches and I would encourage reviews from the > VFS folks as there is a VFS component here, albeit a somewhat small one. > v4 will contain 3 patches: one to introduce struct lsm_xattrs, next to introduce the kfunc, and finally the selftests. > > + > > +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; > > I'm not sure why the "xattrs" and "xattrs_count" local variables are > necessary, especially since they only appear to be used in the sanity > check below. I would suggest just using the values in the struct > directly. > Leftover from the previous implementation, will fix. > > +/** > > + * bpf_init_inode_xattr - set an xattr on a new inode from inode_init_security > > + * @xattr_ctx: inode_init_security xattr state from the hook context > > + * @name__str: xattr name (e.g., "bpf.file_label") > > + * @value_p: dynptr containing the xattr value > > + * > > + * Only callable from lsm/inode_init_security programs. > > + * > > + * Return: 0 on success, negative error on failure. > > + */ > > +__bpf_kfunc int bpf_init_inode_xattr(struct xattr_ctx *xattr_ctx, > > + const char *name__str, > > + const struct bpf_dynptr *value_p) > > +{ > > + return __bpf_init_inode_xattr(xattr_ctx, name__str, value_p); > > +} > > I'm sure there is a reason why you split the code out into > __bpf_init_inode_xattr() as opposed to just putting it directly in this > kfunc, can you help me understand? Not sure, perhaps prior convention, or something with the verifier perhaps. I've removed it in -v4 and everything works. > > diff --git a/include/linux/security.h b/include/linux/security.h > > index 153e9043058f..1f8e84e7dd7e 100644 > > --- a/include/linux/security.h > > +++ b/include/linux/security.h > > @@ -68,6 +68,11 @@ struct watch; > > struct watch_notification; > > struct lsm_ctx; > > > > +struct xattr_ctx { > > + struct xattr *xattrs; > > + int *xattr_count; > > +}; > > I see the bots already pointed this out, and you acknowledged it, but > since I'm looking at this I felt obliged to remind you once again about > the rename to "struct lsm_xattrs" :) > Yeah, sorry about that. =) > Also, looking at this closer, is there a reason why the "xattr_count" > field is an integer pointer and not just an integer? We're passing > the entire struct by reference to the individual LSMs so we shouldn't > need this to get an updated count in the caller and having it as a > regular integer should simplify things slightly (you could also > make it an unsigned int while you are it). > Copy/paste from v2. Will change xattr_count's type to unsigned int. > > --- 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; > > Re: Alexei's comments about this - if you look back at my previous > comments, my concern was around BPF LSMs using too many slots in the > xattr array and causing issues. If the BPF folks want to do that check > in the kfunc located in the LSM framework I'm okay with that; the > important part is that the BPF LSMs don't use more space than they > previously requested. > Ack, will remove this attach-time check. > > diff --git a/security/security.c b/security/security.c > > index 71aea8fdf014..8f82a1352356 100644 > > --- a/security/security.c > > +++ b/security/security.c > > @@ -1334,6 +1334,7 @@ int security_inode_init_security(struct inode *inode, struct inode *dir, > > { > > struct lsm_static_call *scall; > > struct xattr *new_xattrs = NULL; > > + struct xattr_ctx xattr_ctx; > > int ret = -EOPNOTSUPP, xattr_count = 0; > > Since we have the xattr array/pointer and count in the new "lsm_xattrs" > struct, I think we can remove the "new_xattrs" and "xattr_count" local > variables in favor of the fields in the new struct. > Thanks! These will be eliminated in v4. Best, David