[PATCH bpf-next 4/8] bpf, lsm: Let BPF LSM provide xattrs at inode creation

Daniel Borkmann daniel at iogearbox.net
Wed Sep 23 19:11:44 UTC 2026


On 9/23/26 6:57 PM, Paul Moore wrote:
> On Tue, Sep 15, 2026 at 11:07 AM Daniel Borkmann <daniel at iogearbox.net> wrote:
>> From: David Windsor <dwindsor at gmail.com>
>>
>> Many in-kernel LSMs (SELinux, Smack, IMA) store security labels in extended
>> attributes. For these LSMs, atomic labeling during inode creation is
>> critical: if the inode becomes accessible before its xattr is set, it is
>> briefly unlabeled, which can disrupt LSMs making policy decisions based
>> on file labels. Existing LSMs solve this by setting xattrs in the
>> inode_init_security hook, which runs before the inode becomes accessible.
>> BPF LSM programs currently lack this capability because the hook uses an
>> output parameter (xattr_count) that BPF programs cannot write to, and
>> existing kfuncs like bpf_set_dentry_xattr() require a dentry that isn't
>> available until after the inode is accessible.
>>
>> Add a bpf_inode_init_xattr() kfunc that takes the hook's own xattrs and
>> xattr_count arguments, passed through from the program's context, and
>> claims a slot via lsm_get_xattr_slot() on the program's behalf. The
>> xattr_count output argument is exposed to inode_init_security programs
>> as trusted read-only memory, so programs can pass it to the kfunc but
>> cannot modify the count themselves.
>>
>> Reserve BPF_LSM_INODE_INIT_XATTRS slots in bpf_lsm_blob_sizes the way
>> every other xattr-providing LSM does, for the life of the kernel. The
>> framework keys the collection off the reserved slot count, so a kernel
>> built with CONFIG_BPF_LSM=y now allocates the xattr array on every inode
>> creation, whether or not a program sits on the hook.
>>
>> Give the hook a strong prototype in bpf_lsm_proto.c so that its qstr and
>> xattrs arguments are marked __nullable. Both can be NULL for some callers.
>> Without the annotation the verifier otherwise hands the program a trusted
>> non-NULL pointer which it dereferences. Also, keep the hook out of the
>> sleepable set. inode_init_security runs inside the transaction creating
>> the inode, with a journal handle held on ext4 and btrfs and the parent's
>> i_rwsem down, which is why everything on the path allocates GFP_NOFS.
>>
>> Signed-off-by: David Windsor <dwindsor at gmail.com>
>> Co-developed-by: Daniel Borkmann <daniel at iogearbox.net>
>> Signed-off-by: Daniel Borkmann <daniel at iogearbox.net>
>> ---
>>   fs/bpf_fs_kfuncs.c         | 99 ++++++++++++++++++++++++++++++++++++++
>>   include/linux/bpf_lsm.h    | 11 ++++-
>>   kernel/bpf/bpf_lsm.c       | 22 ++++++++-
>>   kernel/bpf/bpf_lsm_proto.c | 15 ++++++
>>   security/bpf/hooks.c       |  1 +
>>   5 files changed, 145 insertions(+), 3 deletions(-)
> 
> @Daniel, you were CC'd on David's previous patches, so I'm guessing
> you saw my objection[1], but just in case you hadn't please look at my
> comments where I requested that David's proposed LSM kfunc be located
> in security/bpf_lsm_kfuncs.c as opposed to fs/bpf_fs_kfuncs.c.  It
> would be really nice if we could sort this out now and avoid having
> this drag out or escalate.

Paul, I reached out to David recently asking whether I could offer some
help with the BPF bits, added some bug fixes and a lot more BPF selftests
as I think the inode xattr init is valuable work and something we need as
well. I just reread this whole thread below given its quite a while back
and didn't follow in too much detail back then.. the location as it is is
perfectly fine, I see no reason to change it, and I guess that makes three
of us then including the VFS folks [0]. In that file there are a number of
other kfuncs as well already related to xattr in context of dentry, files,
etc. I don't see a point at all on endless bike shedding on this, its
perfectly reasonably where this is located. In case you have some technical
comment or found a bug, let me know, happy to address.

   [0] https://lore.kernel.org/bpf/20260625-schnabel-rennmaschine-parieren-bcb352c3cf59@brauner/

> @David, simply for my own understanding, did you ask Daniel to do
> this, or was Daniel operating on his own with this patchset?
> 
> [1] https://lore.kernel.org/linux-security-module/CAHC9VhTS7rSnBqg00ZxNkcZyh_=EeJmn_4z3CTCCxreEEDtTtg@mail.gmail.com/
> 




More information about the Linux-security-module-archive mailing list