freenode
Kernel & Low-Level

BPF LSM gains atomic xattr labeling at inode creation

A bpf-next series lets BPF security programs label new files before they become visible, and closes a verifier hole that allowed trusted-pointer forgery.

BPF LSM programs can now attach security labels as extended attributes while an inode is still being created, matching what built-in Linux security modules have long done.

SELinux, Smack, IMA and similar LSMs store policy labels in xattrs. They set those labels inside the inode_init_security hook so the inode is never visible in an unlabeled state. A brief unlabeled window can break label-based policy decisions. BPF LSM lacked an equivalent path: the hook exposes an output count that programs cannot write, and existing helpers that set xattrs need a dentry that only exists after the inode is already reachable.

David Windsor and Daniel Borkmann posted an eight-part series on the BPF list that closes the gap. A new kfunc claims a slot in the shared xattr array on the program's behalf and fills name and value. The hook's output count is exposed to the program as trusted read-only memory that may be passed through to the kfunc but not mutated by the program itself, so one LSM cannot push another past the array bounds. The design also reserves permanent slots in the BPF LSM blob the way other xattr-providing LSMs do, and keeps the hook non-sleepable because it runs under filesystem journal and lock constraints that demand GFP_NOFS allocations.

The same series hardens the verifier. BPF LSM was routing context access checks through a helper that ignored write versus read, unlike every other tracing-style program type. A program could store a chosen scalar into a context slot, read it back as a trusted pointer of the hook argument type, and hand that pointer to a kfunc for arbitrary kernel access. LSM context access now goes through the same read-only path used elsewhere, with selftests that reject stores into the context.

Selftests cover verifier rules for the new output plumbing, rejection of forged or shifted count pointers, shared slot budgets across LSMs, label inheritance from a parent directory, and refusal of names outside the security.bpf. prefix or beyond name length limits. An ocfs2 adjustment copies xattr names as well as values so BPF-supplied names that live in the same allocation as their values are not left dangling after the security init path frees the array.

The work is aimed at bpf-next. Kernels built with BPF LSM will allocate the xattr array on every inode creation once the series lands, whether or not a program is attached to the hook.