summaryrefslogtreecommitdiff
path: root/security
AgeCommit message (Collapse)Author
21 hoursMerge branch 'headers' of git://git.infradead.org/users/willy/pagecache.gitMark Brown
# Conflicts: # net/ceph/osd_client.c
21 hoursMerge branch 'next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/mic/linux.git
22 hoursMerge branch 'for-next-tpm' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd.git
22 hoursMerge branch 'next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git
22 hoursMerge branch 'next' of ↵Mark Brown
https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm.git # Conflicts: # include/linux/ns/ns_common_types.h
24 hourslandlock: Clean up ruleset validation checksMickaël Salaün
landlock_merge_ruleset() checks for a NULL ruleset after dereferencing it in lockdep_assert_held(). Move the assertion after the check so the defensive path remains effective. The mask-validation comment originated in landlock_add_fs_access_mask() to explain that its WARN_ON_ONCE() checked a caller invariant. It became self-referential when this helper and its network and scope counterparts were inlined into landlock_create_ruleset(). Restate the invariant without naming the caller. Keep both as defensive callee checks. Moving the assertion preserves the NULL check's ability to warn and return -EINVAL, while invalid masks remain warned about and masked. Reported-by: Günther Noack <gnoack@google.com> Closes: https://patch.msgid.link/aobYhIt3vcs2xN0b@google.com Closes: https://patch.msgid.link/aobasxUDQ8b7GYXl@google.com Link: https://patch.msgid.link/20260907103609.113325-1-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
25 hourslandlock: Fix use-after-free of the source's parent directoryNorbert Szetei
current_check_refer_path() reads old_dentry->d_parent without holding a reference nor a lock on it, and then dereferences it in collect_domain_accesses() and in the audit record. A reference on a child does not pin its parent: __d_move() reassigns dentry->d_parent and drops the reference the child held on its former parent. hook_path_rename() is not affected because the rename path calls lock_rename() before the hook, so the source cannot be reparented under it. hook_path_link() has no such protection: filename_linkat() holds a reference on the source dentry but neither locks nor references its parent, so a concurrent rename(2) can reparent the source while security_path_link() runs, and the former parent can then be removed and freed while the hook walks it. A process can trigger this after entering a Landlock domain that handles at least one filesystem access right. The process can then race a linkat(2) loop against rename(2) and rmdir(2): BUG: KASAN: slab-use-after-free in collect_domain_accesses+0x278/0x290 Read of size 4 at addr ffff888160bd53f4 by task llrepro2/549 collect_domain_accesses+0x278/0x290 current_check_refer_path+0x952/0x1120 security_path_link+0x1be/0x320 filename_linkat+0x342/0x6d0 __x64_sys_linkat+0xfa/0x150 Freed by task 562: kmem_cache_free+0x139/0x4c0 i_callback+0x4b/0x80 rcu_core+0x7dc/0x10a0 Take a reference on the dentry selected as the source parent, using dget() for the common-mount-root case and dget_parent() otherwise. Release it after the hierarchy walk and synchronous audit logging. Cc: stable@vger.kernel.org Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER") Signed-off-by: Norbert Szetei <norbert@doyensec.com> Reviewed-by: Günther Noack <gnoack3000@gmail.com> Tested-by: Günther Noack <gnoack3000@gmail.com> Link: https://patch.msgid.link/E9CDD9E6-E960-4DE2-B1AC-5667D52ABB3E@doyensec.com [mic: Clarify the caller, reachability, and reference handling] Signed-off-by: Mickaël Salaün <mic@digikod.net>
36 hoursMerge git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf 7.3-rc2Alexei Starovoitov
Cross-merge BPF and other fixes after downstream PR. Conflicts: kernel/bpf/backtrack.c include/linux/bpf_verifier.h Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2 daysMerge tag 'kmalloc_obj-v7.3-rc2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux Pull kmalloc_obj conversions from Kees Cook: "Another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci" * tag 'kmalloc_obj-v7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/kees/linux: treewide: refresh kmalloc_obj() conversions drm/amd/display: Fix harmless type mismatch in allocation
3 daystreewide: refresh kmalloc_obj() conversionsKees Cook
This is another run of the Coccinelle script for converting kmalloc() family of allocations to kmalloc_obj() via the existing rules in scripts/coccinelle/api/kmalloc_objs.cocci This catches both the set of kmalloc() uses added since the first kmalloc_obj() conversions in v7.0 and adds a large group missed in the first pass due to Coccinelle not interacting well with the cleanup.h scoped_...() family of macros[1]. I worked around this with spatch's "--macro-file" argument to a file with all the scoped_...() macros mapped to Coccinelle's YACFE_ITERATOR[2] as that was the closest viable control flow indicator I could find. Build tested allmodconfig on x86, arm64, arm, loongarch, mips, powerpc, riscv, and s390 with no new warnings. Link: https://lore.kernel.org/lkml/202609021314.8A9C0B8@keescook/ [1] Link: https://github.com/coccinelle/coccinelle/blob/master/standard.h [2] Signed-off-by: Kees Cook <kees+treewide@kernel.org>
3 daysMerge tag 'integrity-v7.3-rc2' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity Pull IMA fixes from Mimi Zohar: - Instantiating the ima_file_truncate and ima_path_truncate LSM hooks resulted in configfs locking issues. configfs files should not be measured, appraised, or audited in the first place, so the builtin policies are updated to exclude them. - IMA audit messages include the filename, which could result in a page fault when the filename doesn't exist - Un-hide the IMA_MEASURE_PCR_IDX Kconfig prompt * tag 'integrity-v7.3-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: ima: allow users to specify the pcr index with IMA_MEASURE_PCR_IDX ima: Check for ERR_PTR from dentry_path() in validate_hash_algo() ima: don't measure/appraise files on configfs configfs: move CONFIGFS_MAGIC definition to magic.h
4 daysima: allow users to specify the pcr index with IMA_MEASURE_PCR_IDXJulian Braha
The IMA_MEASURE_PCR_IDX option is currently not visible in the kconfig frontend, so it always uses its default, 10. This means that the 'range 8 14' is dead code, and users are unable to specify the pcr index value. In a previous discussion, Mimi explained that users should be able to use this config option to specify the pcr index. [1] Let's add a prompt for users to specify the pcr index, when EXPERT is enabled. This dead range was found by kconfirm, a static analysis tool for Kconfig. Link: https://lore.kernel.org/all/1feff118-4afa-4b9c-86f1-271a7a88208f@gmail.com/T/#mc4efa2491b4937eb7c9e532c29ffba516a70e662 [1] Signed-off-by: Julian Braha <julianbraha@gmail.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
5 daysMerge tag 'selinux-pr-20260903' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull SELinux fixes from Paul Moore: "Two SELinux fixes: one to fix how we lookup a BPF token's creator label to prevent a possible TOCTOU, and one to update Ondrej's email address" * tag 'selinux-pr-20260903' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: MAINTAINERS, mailmap: update email address for Ondrej Mosnáček selinux: fix BPF token permission checks
5 daysAutomated merge of 'dev' into 'next'Paul Moore
* dev: selinux: remove unused mls_setup_user_range() selinux: convert selinuxfs inode numbers from unsigned long to u64 selinux: tighten policydb_context_isvalid() checks
6 daysima: Check for ERR_PTR from dentry_path() in validate_hash_algo()Bradley Morgan
dentry_path() returns ERR_PTR(-ENAMETOOLONG) when the path exceeds the buffer. validate_hash_algo() passes the result straight to integrity_audit_msg() without checking. ERR_PTR is not NULL, so integrity_audit_message() sees a valid pointer and calls strlen() on it, which faults: BUG: unable to handle page fault for address: ffffffffffffffdc RIP: 0010:strlen+0x30/0xa0 Call Trace: audit_log_untrustedstring+0x19/0x30 integrity_audit_message+0x366/0x4f0 ima_inode_setxattr+0x512/0x5f0 Check for IS_ERR() and use NULL instead, which makes the audit message skip the name= field instead of crashing. Fixes: 4f2946aa0c45 ("IMA: introduce a new policy option func=SETXATTR_CHECK") Cc: stable@vger.kernel.org Reported-by: syzbot+5ebeb3089ea6439c37be@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/6a8f89e5.1d9ded08.62e62.00bf.GAE@google.com/ Signed-off-by: Bradley Morgan <brads@mainlining.org> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
6 daysima: don't measure/appraise files on configfsFrederick Lawler
IMA measurement of a configfs file causes process_measurement() to hold iint->mutex while performing a kernel_read() to hash it, which re-enters configfs's own file locking (buffer->mutex, frag_sem). Separately, opening any file with O_TRUNC now causes ima_file_truncate() to take iint->mutex to reset the cached action flags, while sb_writers is already held for that mount. When a configfs-backed nvmet namespace is involved, these two independent lock chains combine into a cycle: iint->mutex -> configfs locks -> subsys->lock -> sb_writers -> iint->mutex Add configfs to the builtin don't measure/appraise rules, similarly to other pseudo file systems, so IMA never takes iint->mutex for configfs file in the first place. Reported-by: syzbot+448c2e24b1ceff13ed2a@syzkaller.appspotmail.com Link: https://lore.kernel.org/all/6a77c7cd.b50370da.49fe0.0031.GAE@google.com/ Suggested-by: Mimi Zohar <zohar@linux.ibm.com> Signed-off-by: Frederick Lawler <fred@cloudflare.com> Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
6 dayshardening: Default randstruct off with rust for better allmodconfig supportMark Brown
Currently randstruct does not support rust so we have Kconfig dependencies which prevent rust being enabled when randstruct is. Unfortunately this prevents rust being enabled in allmodconfig, our standard coverage build. randstruct gets turned on by default, then the dependency on !RANDSTRUCT causes rust to get disabled. Work around this by disabling randstruct by default if we have a usable rust toolchain and rust support for the architecture, circular dependencies prevent us directly depending on !RUST. This means we might end up with a configuration that disables both rust and randstruct but hopefully it's more likely go give the expected result. Signed-off-by: Mark Brown <broonie@kernel.org> Acked-by: Miguel Ojeda <ojeda@kernel.org> Link: https://patch.msgid.link/20260901-rust-reverse-randstruct-dep-v4-1-3bfa19efe1fa@kernel.org Signed-off-by: Kees Cook <kees@kernel.org>
7 dayskeys: translate request_key_auth pid for the reading procfs instanceMaoyi Xie
request_key_auth_describe() prints rka->pid into /proc/keys as a raw pid_t in the initial pid namespace. A reader can open /proc/keys through a mount in another pid namespace. That reader sees a number with no meaning there. The number can even name an unrelated task. The line needs VIEW on the key. So the reader either shares the key owner's uid or possesses the key. The fix keeps a struct pid. Commit 4f82f45730c6 ("net ip6 flowlabel: Make owner a union of struct pid * and kuid_t") gave /proc/net/ip6_flowlabel the same storage. The print goes through pid_nr_ns(). It renders against the pid namespace of the procfs instance the line is read through. Commit ad08978ab41c ("ipv6/flowlabel: simplify pid namespace lookup") moved that print to the same anchor. Output through an initial namespace /proc does not change. The line shows 0 for a requestor with no number in that namespace. Translating at read time was the alternative. find_pid_ns() can resolve a recycled number. The line would then name a live task with no connection to the key. A stored struct pid gives 0 instead when the requestor has no number there. Link: https://lore.kernel.org/keyrings/20260809110202.2180410-1-maoyixie.tju@gmail.com/ Fixes: 78b7280cce23 ("KEYS: Improve /proc/keys") Cc: stable@vger.kernel.org # v5.10+ Assisted-by: Claude:claude-opus-5 codeql Signed-off-by: Maoyi Xie <maoyixie.tju@gmail.com> Link: https://lore.kernel.org/r/20260821095935.1864998-1-maoyixie.tju@gmail.com Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
7 dayskeys: fix lost wakeup when reaping a dead key typeKarl Mehltretter
clear_bit() is atomic with respect to the word it modifies, but it is an unordered operation: it implies no memory barrier on either side (Documentation/atomic_bitops.txt). key_garbage_collector() clears KEY_GC_REAPING_KEYTYPE with clear_bit() and calls wake_up_bit() after reaping a dead key type. wake_up_bit() uses a lockless waitqueue check and requires a full barrier after the clear. The existing smp_mb() is before clear_bit(), so nothing orders the clear against that check. The GC can see an empty waitqueue while unregister_key_type() still sees the bit set. The final wakeup is then lost, leaving module unload stuck in wait_on_bit(). Use clear_and_wake_up_bit(). Its clear_bit_unlock() has RELEASE semantics, so the completed GC work stays ordered before the clear, and its smp_mb__after_atomic() orders the clear before the waitqueue check. Fixes: 0c061b5707ab ("KEYS: Correctly destroy key payloads when their keytype is removed") Assisted-by: Claude:claude-fable-5 Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com> Link: https://lore.kernel.org/r/20260821025327.61488-1-kmehltretter@gmail.com Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
8 dayslsm: don't call security_backing_file_free() multiple timesCai Xinchen
I found the following path: alloc_empty_backing-file init_file(&ff->file, xxx) -> file_ref_init(&f->f_ref, 1); // only 1 error = init_backing_file -> security_backing_file_alloc -> rc = call_int_hook(backing_file_alloc, ...) if (unlikely(rc)) security_backing_file_free(backing_file); // first call if (unlikely(error)) { fput(&ff->file); -> if (unlikely(file_ref_put(&file->f_ref))) // zero __fput_deferred(file); -> ____fput -> __fput -> file_free(file); -> backing_file_free(backing_file(f)); -> security_backing_file_free(&ff->file); // second call Currently, only SELinux has the lsm backing_file_alloc hook, and it always return 0. When security_backing_file_free is called for the first time, the blobs pointer is set to NULL. Therefore, double free will not occur in the code. Fixes: 6af36aeb147a ("lsm: add backing_file LSM hooks") Signed-off-by: Cai Xinchen <caixinchen1@huawei.com> [PM: subject line tweaks] Signed-off-by: Paul Moore <paul@paul-moore.com>
8 dayslsm: delete duplicate assignment in lsm_prepare()Cai Xinchen
Delete a duplicate assignment of the LSM blob size variable in lsm_prepare(). Signed-off-by: Cai Xinchen <caixinchen1@huawei.com> [PM: subject and description fixes] Signed-off-by: Paul Moore <paul@paul-moore.com>
8 dayslsm: update the BUILD_BUG_ON() in audit_log_lsm_data()Paul Moore
On 32-bit systems the newly added namespace fields in the common_audit_data struct exceed the BUILD_BUG_ON(sizeof(void *) * 2) size check in audit_log_lsm_data(). Convert the size check to two u64 types to both fit the new fields and move to a size that is not architecture dependent. Fixes: bb20ca26f960 ("lsm: add LSM_AUDIT_DATA_NS for namespace audit records") Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202608131232.Owej9tlx-lkp@intel.com/ Signed-off-by: Paul Moore <paul@paul-moore.com>
8 dayslsm: add LSM_AUDIT_DATA_NS for namespace audit recordsMickaël Salaün
Add a new LSM audit data type LSM_AUDIT_DATA_NS that logs namespace information in audit records. Two fields are provided: - namespace_type: the CLONE_NEW* flag identifying the namespace type, logged in hexadecimal. - namespace_id: the unique 64-bit namespace identifier, retrievable from userspace via NS_GET_ID or listns(2). Unlike the proc inode number (inum), namespace_id is never recycled. For namespace creation denials, namespace_id is 0 because the namespace does not exist yet. A new audit data type is needed because no existing LSM_AUDIT_DATA_* type carries namespace information. The closest alternatives (e.g. LSM_AUDIT_DATA_TASK or LSM_AUDIT_DATA_NONE with custom strings) would either lose the namespace type or require ad-hoc formatting that bypasses the structured audit data union. Cc: Günther Noack <gnoack@google.com> Cc: Paul Moore <paul@paul-moore.com> Reviewed-by: Christian Brauner <brauner@kernel.org> Reviewed-by: Günther Noack <gnoack@google.com> Signed-off-by: Mickaël Salaün <mic@digikod.net> [PM: corrected audit fields in the description, subject tweaks] Signed-off-by: Paul Moore <paul@paul-moore.com>
8 dayslsm: add LSM blob and hooks for namespacesChristian Brauner
All namespace types now share the same ns_common infrastructure. Extend this to include a security blob so LSMs can start managing namespaces uniformly without having to add one-off hooks or security fields to every individual namespace type. Add a ns_security pointer to ns_common and the corresponding lbs_ns blob size to lsm_blob_sizes. Allocation and freeing hooks are called from the common __ns_common_init() and __ns_common_free() paths so every namespace type gets covered in one go. All information about the namespace type and the appropriate casting helpers to get at the containing namespace are available via ns_common making it straightforward for LSMs to differentiate when they need to. A namespace_install hook is called from validate_ns() during setns(2) giving LSMs a chance to enforce policy on namespace transitions. The LSM check runs before ns->ops->install() so the security module can deny the operation before any type-specific installation effects. Individual namespace types can still have their own specialized security hooks when needed. This is just the common baseline that makes it easy to track and manage namespaces from the security side without requiring every namespace type to reinvent the wheel. Cc: Günther Noack <gnoack@google.com> Cc: Paul Moore <paul@paul-moore.com> Cc: Serge E. Hallyn <serge@hallyn.com> Signed-off-by: Christian Brauner <brauner@kernel.org> Link: https://lore.kernel.org/r/20260216-work-security-namespace-v1-1-075c28758e1f@kernel.org Signed-off-by: Mickaël Salaün <mic@digikod.net> [PM: subject tweak] Signed-off-by: Paul Moore <paul@paul-moore.com>
8 dayscred: clarify that task_struct::cred is only for the current taskJann Horn
The `cred` field in task_struct is currently marked as __rcu, but that's not true: It can point to credentials from access_override_creds(), which do not get freed with RCU delay. What actually protects task_struct::cred is that accessing it is only permitted for the current task (except for setting up a child during fork() or tearing down a dead process). (There is currently code in Smack that violates this rule, but that's a bug and causes UAF, I have sent a separate fix for that.) Clarify this, remove the __rcu marker, and remove RCU helpers from all accesses to this field. Signed-off-by: Jann Horn <jannh@google.com> Reviewed-by: Serge Hallyn <serge@hallyn.com> [PM: style tweak in security_init(), applied fixup from JH] Signed-off-by: Paul Moore <paul@paul-moore.com>
8 daysselinux: remove unused mls_setup_user_range()Stephen Smalley
mls_setup_user_range() was a helper for security_get_user_sids(), which was removed by commit ad1ac3d740cc6b8 ("selinux: prune /sys/fs/selinux/user"). Since mls_setup_user_range() has no remaining users, remove it too and any other helpers that only it was using. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
8 daysselinux: convert selinuxfs inode numbers from unsigned long to u64Paul Moore
Starting with commit 0b2600f81cef ("treewide: change inode->i_ino from unsigned long to u64") inode numbers were changed from an 'unsigned long' type to a 'u64' but somehow selinuxfs was lost in the conversion. This patch corrects this oversight and converts selinuxfs to 'u64' inode numbers. Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
8 daysselinux: tighten policydb_context_isvalid() checksStephen Smalley
policydb_context_isvalid() bounds each of user, role, and type but does not require the value to be defined. A crafted policy can declare more identifiers that it defines, so an initial SID or ocontext context whose type is not defined can be inserted into the sidtab and later reach type_attribute_bounds_av() from context_struct_compute_av(), thereby reaching the BUG_ON(!type_val_to_struct[type - 1]). A user with no datum can reach context_struct_to_string() and thereby trigger strlen(NULL). The user and role datums are already NULL-checked further down but only when role is not OBJECT_R_VAL, so an object context can carry an undefined value through. Use policydb_{role,user,type}_isvalid(), which check both the range and that the value has a name, in place of the inline range checks. The name and datum arrays are populated by *_index(), so a value with a name also has a datum. This runs after policydb_index(), so the arrays are populated. The now-redundant NULL guards on role and usrdatum in the OBJECT_R_VAL block can then be dropped. Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
8 daysselinux: fix BPF token permission checksPaul Moore
Avoid multiple lookups of the bpffs creator SID using the token's file descriptor when the same information can be found via the resolved path/dentry (in selinux_bpf_token_create()) or the token itself (in selinux_bpf_map_create() and selinux_bpf_prog_load()). Not only does this simplify the code, it avoids potential TOCTOU issues if the user changes the token file descriptor passed into the kernel. Cc: stable@vger.kernel.org Fixes: 5473a722f782 ("selinux: add support for BPF token access control") Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com> Tested-by: Stephen Smalley <stephen.smalley.work@gmail.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
9 daysbpf, keys: Add a bpf keyring for program signature validationDaniel Borkmann
BPF program signatures can currently be verified against one of the system keyrings (builtin, secondary, platform) or against an arbitrary user/session caller-supplied keyring named through keyring_id. There is nothing in between: the system keyrings need a kernel rebuild or a vouched-for enrollment to rotate a key, while a caller-supplied keyring is fully controlled by the loader and therefore carries no trust on its own (unless explicitly combined with BPF LSM to protect against key tampering). Add a dedicated bpf keyring to fill that gap, modelled after the dm-verity keyring which was added in commit 033724b1c627 ("dm-verity: add dm-verity keyring") and which can eventually be used also via systemd [0] through the same enrollment method as in dm-verity's case. It is selected with the new KEY_SPEC_BPF_KEYRING special key id and gives an operator a place to enroll a BPF-only signing key at boot, specifically scoped to BPF program loading and nothing else in the kernel's trust hierarchy. The id is reserved from the KEY_SPEC space so that the latter is not linked into any process keyring, and lookup_user_key() resolves KEY_SPEC_BPF_KEYRING constant instead of having to look it up via /proc/keys first. By default the keyring is sealed empty at init. Systems that want to provision keys pass bpf.keyring_unsealed=1, which leaves the keyring open for the initrd to add keys to. The keyring is only ever consulted once it is both non-empty and restricted. An unrestricted keyring is ignored. Signed-off-by: Daniel Borkmann <daniel@iogearbox.net> Link: https://github.com/systemd/systemd/pull/43549 [0] Link: https://lore.kernel.org/r/20260828175227.1537793-2-daniel@iogearbox.net Signed-off-by: Alexei Starovoitov <ast@kernel.org>
11 daysMerge tag 'for-next-tpm-7.3' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd Pull TPM updates from Jarkko Sakkinen: "The bulk of this is Ross Philipson's TPM enablement for Trenchboot. That exposes TPM constants, and decouple and improve robustness of tpm_buf a bit in order to implement a minimal early TPM driver. Early boot code will call either SKINIT on AMD or GETSEC[SENTER] on Intel before jumping into kernel's entry point. They re-initalize TPM PCRs but leave up to the early boot code measure initrd, boot_params and Trenchboot associated metadata. The motivation here is just that we would want in future iterations of the series put our full focus to the x86 part of the review, and call it a day as per TPM changes. Further, even if Trenchboot turned out to be empty lottery the worst possible outcome for TPM driver is that things get cleaned up a bit" * tag 'for-next-tpm-7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: tpm-buf: Add TPM buffer support header for standalone reuse tpm-buf: Memory-safe allocations tpm-buf: Remove chip parameter from tpm_buf_append_handle() tpm-buf: Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW tpm: Remove main TPM header from TPM event log header tpm: Move platform specific definitions to the new PTP header tpm: Move TPM common base definitions to the command header tpm: Move TPM2 specific definitions to the command header tpm: Move TPM1 specific definitions to the command header tpm: Initial step to reorganize TPM public headers tpm: st33zp24: Validate locality read result tpm: st33zp24: Return zero on status read failure tpm: tpm_tis_spi: fix nodef CR50 tpm_tis_spi_resume is null tpm: atmel: depend on X86 tpm: Remove redundant dev_err() tpm: tpm_i2c_nuvoton: disable IRQ on wait timeout
13 daysMerge tag 'apparmor-pr-2026-08-26' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor Pull AppArmor updates from John Johansen: "The biggest functional change is Jann Horn's fix for how aparmor is doing stale cred updates after a policy replacement. apparmor: fix cred UAF caused by begin_current_label_crit_section() It moves the update to be done during task_work at the end of the syscall. One major feature is allowing policy to be compressed in userspace instead of after the fact (in kernel) if we need to hold onto it for CRIU/introspection. The other major change is to do with network mediation. It is a lot of code churn but does not do any functional changes to mediation. It moves the code around, and refactors it to use newer patterns for consistency, and in preparation for some improvements in mediation in a future patchset. Features: - support loading compressed policies - add audit mode to provide a mechanism to silence complain messages - refactor network mediation to use new patterns, and prepare to for extended inet mediation (no functional change) Cleanups: - switch website link to https - make include headers self-contained, and fix circular include - constify aa_label, aa_dfa, aa_profile, and aa_perms paraneters - mark static tables and structs as read only - drop use of _confined variant for iteration - refactory mount to use check_perms - refactor network mediation code to be together - refactor xattr attachment, to take the file path - optimize current_label_crit_section() - leverage audit_log_n_untrustedstring() when possible Bug Fixes: - initialized policy lists heads before fail path - fix deadlock in complain-mode change_hat - auditing of mount binary data - fix error debug output in fn_label_build - fix race condition in label replacement - fix unconfined user namespace restriction forced stack - fix error handling for copy_from_user in policy_update - fix out-of-bounds write when null terminating a label vec - fix integer overflow in verify_tags() bounds check - fix cred UAF caused by begin_current_label_crit_section() - use SEND_SIG_NOINFO instead of NULL in aa_audit()" * tag 'apparmor-pr-2026-08-26' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (40 commits) apparmor: policy_int make sure list heads are initialized before fail path apparmor: fix deadlock in complain-mode change_hat apparmor: constify aa_label parameters on read-only query helpers apparmor: constify aa_dfa parameters on read-only compute paths apparmor: constify aa_profile parameters on read-only compute paths apparmor: constify aa_perms parameters that are read-only apparmor: drop use of _confined variant for iteration apparmor: refactory mount to use check_perms apparmor: fix auditing of mount binary data apparmor: add audit mode to provide a mechanism to silence complain messages apparmor: mark static tables and structs as read only apparmor: fix error debug output in fn_label_build apparmor: make table entry count last enum for static tables apparmor: fix race condition in label replacement apparmor: refactor xattr attachment, to take the file path apparmor: fix unconfined user namespace restriction forced stack apparmor: reserve mediation class for packet mediation apparmor: move sock_rcv_skb() next to inet_conn_request apparmor: move netfilter functions next to the LSM network operations apparmor: refactor network socket mediation to support compatibility ...
13 daysapparmor: policy_int make sure list heads are initialized before fail pathJohn Johansen
If profile create fails before policy_init is complete the list heads are not properly initialized causing profile_free() sanity checks to trigger the following splat. AppArmor WARN aa_policy_destroy: (((!list_empty(&policy->profiles) && (&policy->profiles)->prev != ((void *) 0x122 + (0xdead000000000000UL))))): WARNING: security/apparmor/lib.c:509 at aa_policy_destroy+0x164/0x1b0 security/apparmor/lib.c:509, CPU#0: syz.0.17/5541 Modules linked in: CPU: 0 UID: 0 PID: 5541 Comm: syz.0.17 Not tainted syzkaller #0 PREEMPT(full) Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 RIP: 0010:aa_policy_destroy+0x16b/0x1b0 security/apparmor/lib.c:509 Code: 85 ed 7e 4d e8 96 bc 37 fd 5b 41 5c 41 5e 41 5f 5d e9 19 27 4e 07 cc e8 83 bc 37 fd 48 8d 3d 0c f0 d3 0b 48 c7 c6 a4 eb 38 8e <67> 48 0f b9 3a e9 04 ff ff ff e8 66 bc 37 fd 48 8d 3d ff ef d3 0b RSP: 0018:ffffc9000345eaa0 EFLAGS: 00010293 RAX: ffffffff848f530d RBX: ffff88803f734800 RCX: ffff88801af2a580 RDX: 0000000000000000 RSI: ffffffff8e38eba4 RDI: ffffffff90634320 RBP: 0000000000000000 R08: 0000000000000cc0 R09: 00000000ffffffff R10: dffffc0000000000 R11: fffffbfff1d95913 R12: dead000000000122 R13: ffff88803f734800 R14: ffff88803f734828 R15: dffffc0000000000 FS: 00007f5f6a1836c0(0000) GS:ffff88808c519000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055d02407b048 CR3: 0000000012aa9000 CR4: 0000000000352ef0 Call Trace: <TASK> aa_free_profile+0x9d/0x9f0 security/apparmor/policy.c:334 aa_alloc_profile+0x1e4/0x3e0 security/apparmor/policy.c:416 unpack_profile security/apparmor/policy_unpack.c:1153 [inline] aa_unpack+0x17db/0x7430 security/apparmor/policy_unpack.c:1748 aa_replace_profiles+0x226/0x2a20 security/apparmor/policy.c:1183 policy_update+0x234/0x4a0 security/apparmor/apparmorfs.c:505 profile_load+0x1cb/0x320 security/apparmor/apparmorfs.c:522 vfs_write+0x296/0xba0 fs/read_write.c:685 ksys_write+0x150/0x270 fs/read_write.c:739 do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline] do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84 entry_SYSCALL_64_after_hwframe+0x77/0x7f RIP: 0033:0x7f5f6939e0d9 Code: ff c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 e8 ff ff ff f7 d8 64 89 01 48 RSP: 002b:00007f5f6a183028 EFLAGS: 00000246 ORIG_RAX: 0000000000000001 RAX: ffffffffffffffda RBX: 00007f5f69625fa0 RCX: 00007f5f6939e0d9 RDX: 0000000000000041 RSI: 0000200000000400 RDI: 0000000000000003 RBP: 00007f5f6a183090 R08: 0000000000000000 R09: 0000000000000000 R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000001 R13: 00007f5f69626038 R14: 00007f5f69625fa0 R15: 00007ffe23725c18 Reported-by: syzbot+faed97c4ed43bfe7fee5@syzkaller.appspotmail.com Link: https://syzkaller.appspot.com/bug?extid=faed97c4ed43bfe7fee5 Fixes: fe6bb31f590c9 ("apparmor: split out shared policy_XXX fns to lib") Signed-off-by: John Johansen <john.johansen@canonical.com>
14 dayssecurity: Remove pagemap.h includesMatthew Wilcox (Oracle)
The security subsystem does not use the page cache. Removing just the pagemap.h includes isn't quite enough to insulate it from changes to pagemap as it's also pulled in by swap.h and hugetlb.h. Fortunately, security doesn't need either of those so we can lose all three. Now touching pagemap.h causes no rebuilds in the security subsystem. Signed-off-by: Matthew Wilcox (Oracle) <willy@infradead.org>
14 daystpm-buf: Memory-safe allocationsJarkko Sakkinen
Decouple kzalloc from buffer creation, so that a managed allocation can be used: struct tpm_buf *buf __free(kfree) buf = kzalloc(TPM_BUFSIZE, GFP_KERNEL); if (!buf) return -ENOMEM; tpm_buf_init(buf, TPM_BUFSIZE); Alternatively, other allocations are also possible (static data, stack, etc) for example: u8 buf_data[512]; struct tpm_buf *buf = (struct tpm_buf *)buf_data; tpm_buf_init(buf, sizeof(buf_data)); This is achieved by embedding buffer's header inside the allocated blob, instead of having an outer wrapper. Reviewed-by: Stefan Berger <stefanb@linux.ibm.com> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com> Tested-by: Srish Srinivasan <ssrish@linux.ibm.com> Message-ID: <20260522013555.1063716-1-jarkko@kernel.org> Signed-off-by: Ross Philipson <ross.philipson@oracle.com>
14 daystpm-buf: Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOWJarkko Sakkinen
Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW flags into the TPM_BUF_INVALID flag, as their behavior is identical (the only difference being the associated log messages). Message-ID: <20260125192526.782202-11-jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko.sakkinen@opinsys.com> Reviewed-by: Jonathan McDowell <noodles@meta.com> Signed-off-by: Ross Philipson <ross.philipson@gmail.com>
14 daystpm: Initial step to reorganize TPM public headersRoss Philipson
Consolidate TPM1 constants in tpm_command.h and remove duplicate constants from tpm1-cmd.c. Co-developed-by: Daniel P. Smith <dpsmith@apertussolutions.com> Signed-off-by: Daniel P. Smith <dpsmith@apertussolutions.com> Co-developed-by: Alec Brown <alec.r.brown@oracle.com> Signed-off-by: Alec Brown <alec.r.brown@oracle.com> Signed-off-by: Ross Philipson <ross.philipson@gmail.com> Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-08-23Merge tag 'for-next-keys-v7.3' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd Pull TPM update from Jarkko Sakkinen: "Just a single bug fix" * tag 'for-next-keys-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd: KEYS: trusted: Fix TPM teardown ordering
2026-08-21Merge tag 'landlock-7.3-rc1' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux Pull Landlock update from Mickaël Salaün: "This improves observability with Landlock tracepoints support, which required some refactoring for dedicated domain types and common helpers shared with audit code. A LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS flag is also added to improve process-wide domain enforcement consistency. Whiteout files are now correctly handled and tested, and a few other fixes" * tag 'landlock-7.3-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux: (34 commits) landlock: Document tracepoints selftests/landlock: Add landlock_enforce_domain trace tests selftests/landlock: Add scope and ptrace tracepoint tests selftests/landlock: Add network tracepoint tests selftests/landlock: Add filesystem tracepoint tests selftests/landlock: Add trace event test infrastructure and tests landlock: Add tracepoints for ptrace and scope denials landlock: Add landlock_deny_access_fs and landlock_deny_access_net landlock: Add tracepoints for rule checking landlock: Add landlock_enforce_domain tracepoint landlock: Add create_domain and free_domain tracepoints landlock: Add landlock_add_rule_fs and landlock_add_rule_net tracepoints landlock: Add create_ruleset and free_ruleset tracepoints landlock: Consolidate access-right and scope names in a shared header landlock: Decouple the per-denial logging decision from CONFIG_AUDIT landlock: Split denial logging from audit into common framework landlock: Split struct landlock_domain from struct landlock_ruleset landlock: Move domain query functions to domain.c landlock: Prepare ruleset and domain type split samples/landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS to sampler ...
2026-08-21KEYS: trusted: Fix TPM teardown orderingChengfeng Ye
trusted_tpm_exit() drops the TPM chip reference and frees the digest array before unregistering the trusted key type. key_type_lookup() holds key_types_sem for reading until the key operation finishes, while unregister_key_type() takes it for writing. It therefore provides the synchronization point that must precede backend teardown. The current order permits this interleaving: CPU 0 CPU 1 trusted_tpm_exit() key_type_lookup("trusted") put_device(&chip->dev) trusted_tpm_seal() kfree(digests) pcrlock() unregister_key_type() tpm_pcr_extend(..., digests) CPU 1 can consequently dereference the freed digest array. The chip can also be released before callbacks stop using it. KASAN reported: BUG: KASAN: slab-use-after-free in tpm_pcr_extend+0x1f0/0x200 Read of size 2 at addr ffff88810872d000 by task poc/89 Call Trace: tpm_pcr_extend+0x1f0/0x200 pcrlock+0x42/0x70 [trusted] trusted_tpm_seal+0x1b6/0x570 [trusted] trusted_instantiate+0x293/0x340 [trusted] __key_instantiate_and_link+0xb2/0x2b0 __key_create_or_update+0x61e/0xb50 __do_sys_add_key+0x1b8/0x310 Allocated by task 88: __kmalloc_noprof+0x1a7/0x490 do_one_initcall+0xa1/0x390 do_init_module+0x2df/0x840 Freed by task 90: kfree+0x131/0x3c0 trusted_tpm_exit+0x59/0xa0 [trusted] __do_sys_delete_module+0x346/0x510 Move unregister_key_type() before releasing either resource. This stops new lookups and waits for in-flight key operations to finish before the backend state is destroyed. Fixes: 0b6cf6b97b7e ("tpm: pass an array of tpm_extend_digest structures to tpm_pcr_extend()") Cc: stable@vger.kernel.org Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com> Link: https://lore.kernel.org/r/20260731140925.2973492-1-nicoyip.dev@gmail.com Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org> Tested-by: Jarkko Sakkinen <jarkko@kernel.org> Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-08-19Merge tag 'integrity-v7.3' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity Pull integrity updates from Mimi Zohar: - TPM initialization is sometimes delayed until deferred_probe_initcall Since ordering is not guaranteed within the same initcall level, IMA may initialize before the TPM and fall back to TPM-bypass mode. A new config option, CONFIG_IMA_INIT_LATE_SYNC, allows those building the kernel to defer IMA initialization to late_initcall_sync, accepting the integrity risk of missing early measurements in exchange for avoiding TPM-bypass mode. - The raw policy rules are now measured, as well as the complete policy, closing a gap in integrity measurement coverage * tag 'integrity-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity: ima: measure userspace policy writes before parsing ima: add critical data measurement for loaded policy security: ima: rename boot_aggregate when ima is initialised at late_sync security: ima: introduce IMA_INIT_LATE_SYNC option security: lsm: allow LSMs to register for late_initcall_sync init
2026-08-19Merge tag 'Smack-for-7.3' of https://github.com/cschaufler/smack-nextLinus Torvalds
Pull smack updates from Casey Schaufler: - Spelling fix - Code optimization in smackfs - Fix credential mis-uses - Place limits on two of the smackfs interfaces * tag 'Smack-for-7.3' of https://github.com/cschaufler/smack-next: smack: fix cred UAF in smack_file_send_sigiotask() smack: restrict smackfs/{direct,mapped} values to 0-255 smack: deduplicate smackfs/{direct,mapped} file_operations smack: show msgrcv() subject task in audit smack: fix incorrect task context in smack_msg_queue_msgrcv security: smack: fix spelling mistake smack: simplify write handlers of sysfs entries Smack: Fix error in capability bypass
2026-08-19Merge tag 'lsm-pr-20260814' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm Pull LSM updates from Paul Moore: - Remove task_euid() The task_euid(), and Rust counterpart, was never widely used, for good reason, and now that the only user is gone we're removing it to rid ourselves of both dead and funky code. - Documentation improvements Correct some of the kdoc comments for security_task_prctl() and clarify the rust comments on task UID accessors. - Fix a memory leak in the LSM syscall selftests * tag 'lsm-pr-20260814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm: selftests/lsm: Fix memory leak in attr_lsm_count cred: delete task_euid() rust: task: clarify comments on task UID accessors lsm: clarify security_task_prctl() hook documentation
2026-08-19Merge tag 'selinux-pr-20260814' of ↵Linus Torvalds
git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux updates from Paul Moore: - Convert a __get_free_page() call into a kmalloc() call We had some very old code that called out to __get_free_page() for allocating a pathname. There is no reason this couldn't be done with a call to kmalloc() so we've done the conversion and now there is one less __get_free_page() caller in the kernel. - Limit the number of retired/unknown DCCP netlink messages While DCCP is gone from the kernel, there are still userspace tools which try to talk to the kernel about DCCP sockets which were generating SELinux related log noise (unrecognized netlink message). This pull request both limits the log messages to just the first instance and also explains to the user that DCCP support has been removed. - Convert the SELinux strlcat() calls to seq_buf_XXX() calls As part of the effort to drop the strlcat() API from the kernel, the SELinux/IMA code was converted over to using seq_buf_XXX() calls. - Only calculate the SELinux IMA configuration string length once Previously each call to generate a SELinux configuration string for IMA would have to calculate the length of the string. While the contents of the string will likely change over the lifetime of the system, the length of the string will not. Calculate the string length once at boot and reuse the length value throughout the lifetime of the system. - Further validation of the SELinux policy at policy load time Perform additional sanity checks on the policy constraints and types. - Proper cleanup and error handling for selinuxfs init failures We were not properly cleaning up some state in the case where selinuxfs fails to initialize properly. It's somewhat of an academic exercise as a failure to initialize selinuxfs will cause the system to fail on boot, but it's arguably better to make sure we do things the proper way. - Various code cleanups Convert integer flags to boolean types and drop an uncessary goto from the SELinux code. * tag 'selinux-pr-20260814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: validate constraint expression attr and op at load time selinux: compute the IMA configuration settings string length once at boot selinux: replace strlcat() with seq_buf in selinux_ima_collect_state() selinux: suppress warning flood for retired DCCP netlink messages selinux: tighten type validation during policy load selinux: drop unnecessary goto and label from avc_alloc_node() selinux: convert int flags to bool flags in ss/services.c selinux: clean up selinuxfs resources on init failure selinux: hooks: use kmalloc() to allocate path buffer
2026-08-17landlock: Add tracepoints for ptrace and scope denialsMickaël Salaün
Scope and ptrace denials follow a different code path (a domain hierarchy check) than access-right denials, so they need dedicated tracepoints with type-specific TP_PROTO arguments. Complete the denial coverage with: - landlock_deny_ptrace: ptrace access denied by a domain hierarchy mismatch. - landlock_deny_scope_signal: signal delivery denied by LANDLOCK_SCOPE_SIGNAL. - landlock_deny_scope_abstract_unix_socket: abstract unix socket access denied by LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET. TP_PROTO passes the raw kernel object (struct task_struct or struct sock) for eBPF BTF access; the comm and sun_path string fields use __print_untrusted_str() because they hold untrusted input. Unlike the deny_access events, these omit the blockers field: each maps to exactly one denial type named by the event, so the bitmask would always be zero. Like the deny_access events they carry same_exec and logged. Audit logs the task-targeted denials with generic field names (opid, ocomm), but a strongly typed trace event can use role-prefixed names (tracee_pid/tracee_comm, target_pid/target_comm) that match the mainline task-name convention (sched_process_fork's parent_comm/child_comm) and say whose name each field holds; a bare comm= would collide across events. The abstract-unix-socket event reports peer_pid instead, a tracepoint-only field with no audit counterpart. A scope or ptrace verdict compares the subject domain against the other party's domain, so each event also reports that other party's Landlock domain (tracee_domain=, target_domain=, or peer_domain=); the subject domain= alone does not let a consumer redo domain_is_scoped() or domain_ptrace(). It is reported as a scalar ID rather than a domain pointer: a domain object is immutable, but the other task can replace its credential and free the domain that credential referenced, so a stored foreign pointer could dangle before the event is consumed. The scalar ID also honors the tracepoint no-nullable-pointer rule, since the other party is frequently unsandboxed. Passing the foreign domain hierarchy object so an eBPF consumer could walk the other party's ancestry live would lengthen the RCU section on the shared denial path and needs a deferred refcount put, so it is left as a future enhancement. The relational domain-ID field (tracee_domain, target_domain, or peer_domain) is trace-only and is not added to audit records, so audit's denial format is unchanged by this series. Cc: Günther Noack <gnoack@google.com> Cc: Justin Suess <utilityemal77@gmail.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-14-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-08-17landlock: Add landlock_deny_access_fs and landlock_deny_access_netMickaël Salaün
Add per-type tracepoints emitted from landlock_log_denial() when an access is denied: landlock_deny_access_fs for filesystem denials and landlock_deny_access_net for network denials. They use the "deny_" prefix (rather than "check_") to mark that they fire only on a denial, and they complement the check_rule events by making the denial-by-absence case explicit (when no rule matches, no check_rule event fires). Unlike the audit records, these events fire regardless of the audit configuration and the domain's log flags: the user's "disable logging" intent applies to audit records, not to kernel tracing. The logged field records whether the domain's log policy would submit the denial to audit; it is the decision computed once by landlock_log_denial() and passed to both the audit and the tracing emitter, so a stateless ftrace filter can select the audit-visible denials with logged==1. TP_PROTO passes the denying hierarchy node, not the task's current domain, so domain_id reports the specific node that blocked the access, matching audit record semantics. (check_rule instead passes the current domain, which it needs to size its per-layer array.) same_exec is also passed explicitly because it is computed from the credential bitmask and is not derivable from the hierarchy pointer alone. The denial field is named blockers to match the audit record field. The filesystem path comes from the request's audit data. Its type selects which union member holds the object, exactly as dump_common_audit_data() selects it (a path, a file's path, an ioctl op's path, or a bare dentry); reading the wrong member would dereference garbage, so every reachable type has an explicit case and an unexpected one is flagged with WARN_ONCE() instead of misread. Path-backed types resolve via d_absolute_path() (as landlock_add_rule_fs does) and the bare-dentry case via dentry_path_raw(). The inode number is read defensively. A filesystem denial can carry a negative dentry (no backing inode), for example a denied creation, so the event mirrors the guard in dump_common_audit_data() and reports inode 0 rather than dereferencing a NULL inode. The sibling fs tracepoints do not need the guard: a dentry that matches a rule during an access check, or one opened to add a rule, always has a backing inode. Landlock tracepoints are reachable by unprivileged sandboxees, so a denial on a negative dentry with the event enabled must not fault the kernel. Cc: Günther Noack <gnoack@google.com> Cc: Justin Suess <utilityemal77@gmail.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-13-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-08-17landlock: Add tracepoints for rule checkingMickaël Salaün
Merge landlock_find_rule() into landlock_unmask_layers() so rule pointers stay inside the domain implementation while unmask checking gets the matched rule it needs for the check_rule tracepoint. landlock_unmask_layers() now takes a landlock_id and the domain instead of a rule pointer. A rename or link evaluates the same dentry against both renamed parents, so this path now looks the rule up once per parent; collapsing that back to a single lookup is left to a follow-up. Emit, via the per-type wrappers unmask_layers_fs() and unmask_layers_net(), the rights each matching rule grants at every domain layer. The events carry this as a dynamic per-layer array (up to LANDLOCK_MAX_NUM_LAYERS entries) reserved from the trace ring buffer, not the caller's stack, and rendered symbolically per layer. A WARN_ON_ONCE() in __trace_landlock_fill_layers() flags a rule whose layer levels fall outside the domain range or are unsorted, a cannot-happen case; the zero-filled slots keep the rendered output and the array bounds safe regardless. Setting allowed_parent2 to true for non-dom-check requests when get_inode_id() returns false preserves the pre-refactoring behavior: a negative dentry (no backing inode) has no matching rule, so the access is allowed at this path component. Before the refactoring, landlock_unmask_layers() with a NULL rule produced this result as a side effect; now the caller must set it explicitly. Name the trace-only check_rule fields so each printk label equals its ring-buffer field name and works directly as an ftrace filter: the request field is labelled access_request= and the per-layer array is named grants. Values audit also logs keep audit's label (domain=, ruleset=) so a single filter works across trace and audit. Cc: Günther Noack <gnoack@google.com> Cc: Justin Suess <utilityemal77@gmail.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-12-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-08-17landlock: Add landlock_enforce_domain tracepointMickaël Salaün
The landlock_create_domain event records that a domain was created, once, before thread-sync. It cannot tell which threads end up enforcing it: a successful landlock_restrict_self(2) with LANDLOCK_RESTRICT_SELF_TSYNC applies the domain to the caller and every eligible sibling. Creation (the operation) and enforcement (the per-thread outcome) are distinct. Add landlock_enforce_domain(domain, complete, process_wide), emitted once per thread the domain is applied to, strictly after that thread's commit_creds(), so it fires only for a thread that is enforcing the domain, never speculatively; an aborted operation emits none. The lifecycle now reads create -> enforce* -> free. The two booleans name properties, not the implementation: - complete: marks the single event that concludes the operation. It names the outcome, the set is now enforced, not which thread finishes, which the contract leaves unspecified. - process_wide: means every eligible thread of the process is covered. It is set race-free by either establishing path, thread-sync or a single-threaded process, so complete && process_wide is the whole-process-enforced guarantee. The requesting thread and source ruleset are not repeated here: they are on create_domain (joined via domain->hierarchy->id) and on the immutable domain->hierarchy->details. Source ruleset means the ruleset_id and ruleset_version recorded on create_domain, not the ruleset object, which the caller may close before enforcement. Cc: Günther Noack <gnoack@google.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-11-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-08-17landlock: Add create_domain and free_domain tracepointsMickaël Salaün
Add a landlock_create_domain tracepoint emitted from landlock_restrict_self() after the new domain is created, so a consumer can correlate the source ruleset with the resulting domain. The flags-only path (ruleset_fd == -1) creates no domain and emits no event. Move the ruleset lock acquisition from landlock_merge_ruleset() to the caller so the lock is held across both the merge and the tracepoint emission, giving an eBPF program a consistent ruleset snapshot. Release it before the thread-sync: holding ruleset->lock across landlock_restrict_sibling_threads() would deadlock a sibling blocked on the same lock. The event therefore fires before the (rare) thread-sync failure path; when that path aborts the just-created domain, the matching free_domain event fires so the create/free pair stays balanced. Add a landlock_free_domain tracepoint that fires when a domain's hierarchy node is freed. The hierarchy node is the lifecycle boundary because it represents the domain's identity and outlives the domain's access masks, which may still be active in descendant domains. A domain freed without ever being committed to a credential was never visible to user space, so free_domain is suppressed for it. This is tracked by a new landlock_log_status value, LANDLOCK_LOG_UNCOMMITTED, which is also the zero value so a hierarchy whose initialization failed defaults to not observable. A hierarchy is born UNCOMMITTED and is promoted to LANDLOCK_LOG_PENDING (or LANDLOCK_LOG_DISABLED when logging is off) right after its create_domain event fires; a thread-sync failure does not reset it, so an aborted domain that already emitted create_domain still emits the matching free_domain. Promoting right after the event, rather than at commit_creds() time, avoids a race: on a successful thread-sync the sibling threads commit the new domain in lockstep before landlock_restrict_self() returns, so the shared domain may already have moved to LANDLOCK_LOG_RECORDED through a plain store, and a late promotion would race that store and could unbalance the domain allocation and deallocation audit records. Cc: Günther Noack <gnoack@google.com> Cc: Justin Suess <utilityemal77@gmail.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-10-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-08-17landlock: Add landlock_add_rule_fs and landlock_add_rule_net tracepointsMickaël Salaün
Add tracepoints for Landlock rule addition, landlock_add_rule_fs for filesystem rules and landlock_add_rule_net for network rules, so trace consumers can correlate filesystem objects and network ports with their rulesets. Both are emitted under the ruleset lock (asserted in TP_fast_assign) so an eBPF program reads the ruleset, including the rule just inserted, in a consistent snapshot. Add a version field to struct landlock_ruleset, gated on CONFIG_TRACEPOINTS like the id field and incremented under the ruleset lock on each successful landlock_add_rule(2), including when it only extends an existing rule's access rights. It fills the existing 4-byte hole after usage, so the struct does not grow. Pairing the ruleset ID with the version lets a later restrict_self event record the exact ruleset revision merged into a domain. Resolve the filesystem rule's absolute path with d_absolute_path() rather than the d_path() audit uses: d_absolute_path() produces namespace-independent paths that do not depend on the tracer's chroot state, making trace output deterministic regardless of mount namespace configuration. Distinguish the error cases as "<too_long>" (-ENAMETOOLONG) and "<unreachable>" (anonymous files or detached mounts). Also add __trace_print_untrusted_str(), a static inline helper in the header guarded by CREATE_TRACE_POINTS: it escapes separators, quotes, backslashes, and non-printable bytes via string_escape_mem() so an untrusted string (the path here, process names in later denial events) cannot inject field separators or control characters into the ftrace text output. Cc: Christian Brauner <brauner@kernel.org> Cc: Günther Noack <gnoack@google.com> Cc: Justin Suess <utilityemal77@gmail.com> Cc: Masami Hiramatsu <mhiramat@kernel.org> Cc: Mathieu Desnoyers <mathieu.desnoyers@efficios.com> Cc: Steven Rostedt <rostedt@goodmis.org> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-9-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>