Re: [PATCH v2 1/2] bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling

Song Liu <[email protected]>
Newsgroups org.kernel.vger.linux-integrity,org.kernel.vger.bpf,org.kernel.vger.linux-fsdevel,org.kernel.vger.linux-kernel,org.kernel.vger.linux-security-module,org.kernel.vger.selinux
Message-ID <CAPhsuW6sy2cdC4B7Z48-5A-yVX6fmVWxS_fWVjQxiX95KeUguw@mail.gmail.com>
On Mon, May 4, 2026 at 10:14 PM Paul Moore <[email protected]> wrote:
[...]
> > diff --git a/fs/bpf_fs_kfuncs.c b/fs/bpf_fs_kfuncs.c
> > index 9d27be058494..193accc00796 100644
> > --- a/fs/bpf_fs_kfuncs.c
> > +++ b/fs/bpf_fs_kfuncs.c
> > @@ -10,6 +10,7 @@
> >  #include <linux/fsnotify.h>
> >  #include <linux/file.h>
> >  #include <linux/kernfs.h>
> > +#include <linux/lsm_hooks.h>
> >  #include <linux/mm.h>
> >  #include <linux/xattr.h>
> >
> > @@ -353,6 +354,97 @@ __bpf_kfunc int bpf_cgroup_read_xattr(struct cgroup *cgroup, const char *name__s
> >  }
> >  #endif /* CONFIG_CGROUPS */
> >
> > +static int bpf_xattrs_used(const struct lsm_xattr_ctx *ctx)
> > +{
> > +       const size_t prefix_len = sizeof(XATTR_BPF_LSM_SUFFIX) - 1;
> > +       int i, n = 0;
> > +
> > +       for (i = 0; i < *ctx->xattr_count; i++) {
> > +               const char *name = ctx->xattrs[i].name;
> > +
> > +               if (name && !strncmp(name, XATTR_BPF_LSM_SUFFIX, prefix_len))
> > +                       n++;
> > +       }
> > +       return n;
> > +}
[...]
> > +
> >  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;

We need to mark bpf_init_inode_xattr with KF_RCU (requires a trusted
pointer), then we can remove this check above.

> >                 return 0;
> > +       }
> >         return -EACCES;
> >  }
>
> Perhaps I'm simply not seeing it, but is there a check to ensure that
> there is only one BPF LSM calling into security_inode_init_security()
> at any given time?  With the BPF LSM only reserving a single xattr
> slot, multiple loaded BPF LSM programs providing
> security_inode_init_security() callbacks will be a problem.

I don't think there is such a check. Also, a single BPF LSM function
may call the kfunc multiple times, which is also problematic.

I think we will need to make the default bigger, and also introduce
some realloc mechanism for the worst case scenario. This should
work, but the code might be a bit messy.

Thanks,
Song

>
> > diff --git a/include/linux/security.h b/include/linux/security.h
> > index 41d7367cf403..a2fc72e63ada 100644
> > --- a/include/linux/security.h
> > +++ b/include/linux/security.h
> > @@ -68,6 +68,11 @@ struct watch;
> >  struct watch_notification;
> >  struct lsm_ctx;
> >
[...]
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.