mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-10-26 10:57:38 +08:00
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. Co-developed-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: David Windsor <dwindsor@gmail.com> Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Signed-off-by: Alexei Starovoitov <ast@kernel.org> Link: https://patch.msgid.link/20260915150739.284189-5-daniel@iogearbox.net