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 directly 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.
This series introduces the bpf_init_inode_xattr() kfunc, which takes
the combined inode_init_security xattr context argument to access
xattrs and xattr_count, and internally writes to xattr_count via
lsm_get_xattr_slot().
v4:
- introduce struct lsm_xattrs in separate patch (Alexei, Paul)
- rename struct xattr_ctx to struct lsm_xattrs (Paul)
- make lsm_xattrs.xattr_count unsigned int (Paul)
- drop new_xattrs/xattr_count locals in
security_inode_init_security() (Paul)
- fold __bpf_init_inode_xattr() into bpf_init_inode_xattr() (Paul)
- drop bpf_fs_kfuncs_filter() attach-point check; rely on verifier
type enforcement (Alexei)
- drop attach-time cap; enforce slot budget in the kfunc (Alexei)
- allocate the combined xattr with GFP_NOFS (sashiko-bot)
- replace init_inode_xattr_attach_cap selftest with runtime
init_inode_xattr_slot_limit
v3:
- rename struct lsm_xattr_ctx to struct xattr_ctx (Paul)
- increase BPF_LSM_INODE_INIT_XATTRS to 4 (Song)
- enforce per-hook attachment cap at attach time to prevent
runtime rejection (Paul)
- add init_inode_xattr_attach_cap selftest
v2:
- pass the xattr state as a combined context object and drop the
verifier fixup path (Kumar)
- restrict bpf_init_inode_xattr labels to bpf.* namespace (Matt)
- cap bpf_init_inode_xattr() at BPF_LSM_INODE_INIT_XATTRS slots per
invocation (AI)
David Windsor (3):
security: pass inode_init_security xattrs via struct lsm_xattrs
bpf: add bpf_init_inode_xattr kfunc for atomic inode labeling
selftests/bpf: add tests for bpf_init_inode_xattr kfunc
fs/bpf_fs_kfuncs.c | 79 +++++++++++
include/linux/bpf_lsm.h | 3 +
include/linux/evm.h | 9 +-
include/linux/lsm_hook_defs.h | 4 +-
include/linux/lsm_hooks.h | 16 +--
include/linux/security.h | 5 +
kernel/bpf/bpf_lsm.c | 1 +
security/bpf/hooks.c | 1 +
security/integrity/evm/evm_main.c | 8 +-
security/security.c | 24 ++--
security/selinux/hooks.c | 4 +-
security/smack/smack_lsm.c | 27 ++--
tools/testing/selftests/bpf/bpf_kfuncs.h | 5 +
.../selftests/bpf/prog_tests/lsm_kfuncs.c | 129 ++++++++++++++++++
.../bpf/progs/test_init_inode_xattr.c | 31 +++++
15 files changed, 299 insertions(+), 47 deletions(-)
create mode 100644 tools/testing/selftests/bpf/prog_tests/lsm_kfuncs.c
create mode 100644 tools/testing/selftests/bpf/progs/test_init_inode_xattr.c
base-commit: e771677c937da5808f7b6c1f0e4a97ec1a84f8a8
--
2.53.0