mirror of
https://github.com/torvalds/linux.git
synced 2026-09-23 13:14:02 +02:00
master
7104 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
4a910e594a |
selinux/stable-7.3 PR 20260919
-----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmqvPSwUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXP1rBAAkK6sP+lzXynr/abxWio9UCvlN6NF jqMXtKeUeLNg/lJakXKhja/FGaK9w+Rm+zlXQQvVE7YAO5Db758JzCXMTHlK6etD T5d+GVdZj/oVcAvfGhov0guNHZqcfKTGWOXKtGV8RQWYL+f6IC1IIHnz9wNeWIfY emkfOTgAJpCkX9nXS5xTdQNUiPkUV80LFGqxXCMhxiumvyzqOhUteytfNh3UXXcs ldOWRBstUumudBe/MJR09REtQve3emHc7bZUAxSKwXxzdOPTf7UEy4Y7QXCN3Opn Dn6Dsrt6lnpIZyzUK/eOnZvQ639gDqTMW2XTmin0JIf2KGG/PhqnvOT07hOPl+X5 wqXh2wCFn+tXVi5t+S2myMUVZK56GwfRH9kMCo6ca1Ui36iYYEeoJYt7z5tsE6P5 YBdvKKJ/MPR1/uEwP/TB3UDK0o4OBjyujc6/Ka5iBoIHXKpx7MBLOo/Q0h/Wu2A0 7HYvG/4lYdWp3p5iR8cdZ+ZgdTQDWi6t5BD3JWOfWi1gHCeGgZCHTCZ9mdSoFS18 9GpXFXTR4yM5pfwxQEAu6jFH0esSB92HJBd/yS7sU8EIUQ+0XmOge+gVPifMrhWj yOHCR7hlAYE5ds51w3ZVOYI0slkYImqCHEdlCz1DiKzyLmQQmfJvshOIvBCl7uwn LRHu6Mo0cEBMAvc= =kiQE -----END PGP SIGNATURE----- Merge tag 'selinux-pr-20260919' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux Pull selinux fixes from Paul Moore: - Ensure that the cached SELinux access decisions are correct - Fix the SELinux overlayfs code to properly track the top-level/user information on multiple stacked overlayfs filesystems - Fix the SELinux overlayfs code to properly enforce mprotect() access control policy on all of the different layers in multiple stacked overlayfs filesystems * tag 'selinux-pr-20260919' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux: selinux: recheck intermediate backing files on mprotect() selinux: preserve user SID across nested backing files selinux: always fill AVC decision in avc_has_perm_noaudit() |
||
|
|
78fc54b934 |
selinux: recheck intermediate backing files on mprotect()
mprotect() can be used to bypass the SELinux checks that mmap() performs
against the intermediate layers of a stacked filesystem.
mmap() checks every backing layer as the request descends through the
stack. mprotect() only has the lowest backing file in vma->vm_file, so it
rechecks the top-level user and the lowest mounter, but skips the mounters
of every layer in between. With two nested overlayfs mounts and a policy
denying mounter_t -> middle_file_t:file { execute }, a direct
mmap(PROT_EXEC) is denied:
avc: denied { execute } for pid=71 comm="nested_exec"
path="/payload" dev="overlay" ino=9
scontext=user_u:base_r:mounter_t
tcontext=user_u:object_r:middle_file_t tclass=file permissive=0
while mmap(PROT_NONE) followed by mprotect(PROT_EXEC) succeeds.
Preserve each intermediate path, mounter SID and file-description SID in
the backing-file security blob, copying the saved entries when another
backing layer is opened. Allocate the array only for nested backing files,
and release it and the path references in the backing_file_free hook.
During mprotect(), recheck fd { use } and the requested inode permissions
for every saved mounter, and include the intermediate layers in the execmod
checks. Policy for nested stacking may then need to grant intermediate
mounters what a direct mmap() already requires, and execmod on intermediate
labels for binaries using text relocations.
Tested on arm64 QEMU with a small BusyBox initramfs and a purpose-built
SELinux policy, on a mainline tree containing
commit
|
||
|
|
8c0c602202 |
selinux: preserve user SID across nested backing files
SELinux saves the user file SID in a backing-file security blob so it
remains available after mmap() replaces vma->vm_file with a backing file.
For nested backing files (overlayfs over overlayfs, or FUSE passthrough
backed by overlayfs), user_file may itself be a backing file. Its
fsec->sid is the SID of the mounter that opened it, rather than the user
that opened the top-level file. mprotect() then checks fd { use } against
the mounter SID. This can incorrectly deny access without a domain
transition, or check the wrong target SID after one.
Copy the saved user SID when user_file is a backing file. Keep using the
regular file SID for the first backing layer.
With two nested overlayfs mounts and SELinux enforcing,
mprotect(PROT_READ) returns EACCES with an fd { use } denial against the
mounter SID. With this change, mprotect() succeeds.
Tested on arm64 QEMU with a small BusyBox initramfs and a purpose-built
SELinux policy. The original test was also repeated with Fedora Cloud
Base 44 userspace and gave the same result.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
8861db3051 |
selinux: always fill AVC decision in avc_has_perm_noaudit()
avc_has_perm_noaudit() is documented to return a copy of the access
decision in @avd, but its early return for an empty requested permission
set leaves the buffer untouched. All callers pass an uninitialized
stack variable and afterwards feed it to avc_audit(), and the inode hook
even stores it in the per-task decision cache.
Fill in a deny-all, audit-all decision, similar to avd_init(), so every
caller receives a defined value at no cost on the hot path.
Cc: stable@vger.kernel.org
Fixes:
|
||
|
|
8697c431e2 |
KEYS: encrypted: fix integer overflow of datablob_len
encrypted_key_alloc() stores datablob_len in a u16. It is computed from
multiple string and payload lengths. If the result exceeds U16_MAX, the
assignment truncates the allocation size. KASAN reports a 32760-byte
slab-out-of-bounds write when __ekey_init() copies the master key
description into the undersized buffer.
The total payload length stored in key->datalen is also a u16. Use
check_add_overflow() to reject values that do not fit either destination,
and use kzalloc_flex() for the flexible-array allocation.
Fixes:
|
||
|
|
114f00d738 |
KEYS: trusted: Fix tpm2_load_cmd() boundary check
tpm2_load_cmd() does boundary checks against the ASN.1 size i.e.,
payload->blob_len. Address this by passing the decoded blob size to
tpm2_load_cmd(), and use it for the boundary checks.
Cc: stable@vger.kernel.org # v5.13+
Fixes:
|
||
|
|
0d6a4268b0 |
keys: translate request_key_auth pid for the reading procfs instance
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 |
||
|
|
2725ab3f5a |
keys: fix lost wakeup when reaping a dead key type
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:
|
||
|
|
d41d0021a6
|
landlock: Test trace path output boundaries
Use focused KUnit tests to exercise the renderer's internal boundary and composition contracts with synthetic scratch states, including both sibling-helper evaluation orders. Check the exact output and reservation boundaries, including a four-byte octal escape accepted at exact capacity and rejected one byte short. Also verify an unchanged cursor on failure, that bracketed process names and embedded NUL bytes remain data, and that input ellipsis bytes are escaped rather than mistaken for the raw truncation marker. The composition test requires generic trace output helpers. Enable CONFIG_FTRACE and CONFIG_SCHED_TRACER because the latter selects the otherwise-hidden CONFIG_TRACING support required by trace_print_flags_seq(). Use kselftests to exercise the complete tracefs path for both affected filesystem events. A valid path containing 2640 spaces exceeds the scratch output budget. Require its escaped prefix to end in the raw UTF-8 ellipsis while access_rights and blockers remain intact. This division keeps the exact safety contract compiler-independent while proving that real tracepoints preserve their surrounding symbolic fields. The end-to-end assertions fail after a full fix revert with both GCC and Clang, while the composition KUnit test fails if the scratch reserve is removed. Cc: Günther Noack <gnoack@google.com> Link: https://patch.msgid.link/20260907154401.124362-2-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
d3df7ed468
|
landlock: Clean up ruleset validation checks
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 Reviewed-by: Günther Noack <gnoack@google.com> Link: https://patch.msgid.link/20260907103609.113325-1-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
2c6dc79253
|
landlock: Fix use-after-free of the source's parent directory
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:
|
||
|
|
1fc5a74b10 |
kmalloc_obj conversions for v7.3-rc2
- Run scripts/coccinelle/api/kmalloc_objs.cocci for v7.3 -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRSPkdeREjth1dHnSE2KwveOeQkuwUCapuwVwAKCRA2KwveOeQk u5EeAP9TS7K4iVlw3KlZHuLIK2q+CQfALPepcu+ME2lO5dta4gEAxCTi0ZXmU7OT XbmWUd+DTkKNYCBW8E6Lvn72Er13uQs= =ZtN4 -----END PGP SIGNATURE----- Merge tag 'kmalloc_obj-v7.3-rc2' of 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 |
||
|
|
3a2c4d55e3 |
treewide: refresh kmalloc_obj() conversions
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> |
||
|
|
4d7d9486c0 |
integrity-v7.3-rc2
-----BEGIN PGP SIGNATURE----- iIoEABYKADIWIQQdXVVFGN5XqKr1Hj7LwZzRsCrn5QUCapsP/BQcem9oYXJAbGlu dXguaWJtLmNvbQAKCRDLwZzRsCrn5b2gAQC3ms2HRoZolscMWqnUNoi5SmPpwcV2 v/ojwDc1TnS9HAEA/604QYihEvRQzKQwEyF6W6b83w22tyWKhDW1a0d7KQ4= =/Hd6 -----END PGP SIGNATURE----- Merge tag 'integrity-v7.3-rc2' of 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 |
||
|
|
6903878d46 |
ima: allow users to specify the pcr index with IMA_MEASURE_PCR_IDX
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> |
||
|
|
a500db7819 |
selinux/stable-7.3 PR 20260903
-----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmqZ2MkUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXPIuw/+OzHPcHAwO9q+ZX6jysmxZqSR+X7w NmvTTMGgKA+J2bhmRxuLTApzfx8w0IOq5ZXrPSysszophVpwvtH+UqHr2wuC9pcb 0LO2vfJ4hr44+EKcajbjbwRf1zNpwjCYnIw2g6W5QdNFvnJVKoRLcYdUZzp2dVMl Q5hLeI2irijCOqxeIC4APOyXXUHhg418czvapq4M8MZtOcEICgkbdLYs/fglmo6M 8i90j+HShcbOIH6hO0VDAAnRyYS8JkRFhzXIzSKKf3dtQbUlAwl97laUT2C5jcwr zQmRfnsasGGUQj19hW73Ksn6MuHhMb7XKafbL+De3jD2yHpHEvgrbjUllRBaDjp1 J7V1q8B+FolD/T/Dceghs58lQk736KZvGvLEfoYiVde8BuhE0kqJWupf+KqECj18 Zv8iVuyBC9PkGQPeVTV3V0VPZBvgZCrWhaiVAXRYOY/KqxqXGIcjgeuPU+7VNYl8 lzvZDULYOJeiMSvkStFKy6RDtUtpxaMV4Pv3ZyRFX8p8QviyC/4WXy8DKlGkDCEn 3TBX+PgCC8mGjRegM6GQXp74h3qZ0nAzrcThqaGTQlKqD6SUFwQawes5aRR4GT8j idiRGm6zYoCvFmZ2YFkZ1/LNHkouLLClCOJ4hXcpl19mka/qtASneKJOxPI8cA7Z ZrZQkVNNJipKu1s= =/GJM -----END PGP SIGNATURE----- Merge tag 'selinux-pr-20260903' of 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 |
||
|
|
8861f6d5c0 |
ima: Check for ERR_PTR from dentry_path() in validate_hash_algo()
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:
|
||
|
|
8e22ce504f |
ima: don't measure/appraise files on configfs
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> |
||
|
|
2625480a1b |
hardening: Default randstruct off with rust for better allmodconfig support
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> |
||
|
|
77d499e61d |
selinux: fix BPF token permission checks
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:
|
||
|
|
afe0579334 |
Hi,
I had to think a lot how to put this into few paragraphs. I hope this will makes sense to you and I'm not too confusing. The bulk of this pull request are Ross Philipson's TPM enablers for the Trenchboot patch series. The commits expose 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. BR, Jarkko -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCapClFwAKCRAaerohdGur 0vM5AQDnmMUmfGD4aNBKx/b2gxPIgBy8KTGLDUp5sUSHGVGjuAEAzMLSz3BtTXSV 7GaPKWp81egVjgp5/zxTbA83mEwfAwk= =Pq4i -----END PGP SIGNATURE----- Merge tag 'for-next-tpm-7.3' of 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 |
||
|
|
8fefe68784 |
+ 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 Fies
- 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()
-----BEGIN PGP SIGNATURE-----
iQIzBAABCgAdFiEE7cSDD705q2rFEEf7BS82cBjVw9gFAmqOlFAACgkQBS82cBjV
w9ic7g//QBqYCtrRYA549PvSdHRcyKoVVCRWEmmCXfGaqB/e1lcZoK5XEngcUmzx
ErtFDlGpziQUsXELNA/juZQEc9Me2359nyLQ0ninAJnLI1L1uCvEub1x9mnD1RVP
Hk64rMtsfkumGz9Dwpi+eM5HmWu/5yEojCnzj4DDnB6xCuzRZaUyrhBfmJfLrQ99
mZSez7i7XzVmSohc6BY2b7zTWv6DHVKgCD4uU1t7hcwVU4gvMj6u1u2bTagE0RgZ
HDyM0wxOIvCw34pqhftyx6+2PCeYDyuSPmYhOYggiskIRy4qoDxPi4WDZUc5CKMg
n3EVOzGxnh7nAOGJ+ue2OwWW/Rc40dT8eTPHFOpiblMwoxWACcSSRPQH7n4NboUi
ZTwAo3y8pI79svBrQFiJiCtZOHPiVac5jurUlj8+9LYhjCpdHtBuO5d7hUtnjSJ0
s+omefw8RqLtbQpCY4E23j69GMSQSFNyARpU3VI2BCChuIuKUS5n0bnthR9ggmQR
j5quZNytHDp0yguDY2vL5+QdqAFIUUNEglFKFMzMzCf6Us5Esjw7VFcT8IfhFeHj
3aBu9wdLam3E7LkDZtGvyYbT3onuCqb9ulT/NbGbA3LUctSDfe55YL0lRtCTi+yg
+0K7MsDVR+IuVMR3bIhg/EhljAb+hGcJuqVP+wEN0KIDlQuTOvA=
=Q11v
-----END PGP SIGNATURE-----
Merge tag 'apparmor-pr-2026-08-26' of 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
...
|
||
|
|
3daad923a8 |
apparmor: policy_int make sure list heads are initialized before fail path
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:
|
||
|
|
3d9e043dab |
tpm-buf: Memory-safe allocations
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> |
||
|
|
0b9551c189 |
tpm-buf: Merge TPM_BUF_BOUNDARY_ERROR and TPM_BUF_OVERFLOW
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> |
||
|
|
e06f28d32f |
tpm: Initial step to reorganize TPM public headers
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> |
||
|
|
8552019d09 |
Hi,
My v7.3 pull request for keyrings has just a single bug fix. BR, Jarkko -----BEGIN PGP SIGNATURE----- iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCaopfmQAKCRAaerohdGur 0j2FAP9b+9qHmkAomhpDKy2aSPu95s4/Fq8EAt9UKghdI4RrUwEAjP/nMnImt60K +nQwwu+Y1gBaSwcYw9IRL9dyn/bNAwo= =xk5R -----END PGP SIGNATURE----- Merge tag 'for-next-keys-v7.3' of 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 |
||
|
|
7199989f3f |
Landlock update for v7.3-rc1
-----BEGIN PGP SIGNATURE----- iIYEABYKAC4WIQSVyBthFV4iTW/VU1/l49DojIL20gUCaoa8/RAcbWljQGRpZ2lr b2QubmV0AAoJEOXj0OiMgvbSSjMBAIq+/dIjMVUddtyqRlWKMfBQqokU4Dl5JeHB Y4Jh61idAQCihXimNu+TOuX1zc80eBR+IzDYaAU8ZGcK079hmGO5Bw== =TKoa -----END PGP SIGNATURE----- Merge tag 'landlock-7.3-rc1' of 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 ... |
||
|
|
5e2d672280 |
KEYS: trusted: Fix TPM teardown ordering
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:
|
||
|
|
a51ec5e8e5 |
integrity-v7.3
-----BEGIN PGP SIGNATURE----- iIoEABYKADIWIQQdXVVFGN5XqKr1Hj7LwZzRsCrn5QUCaoTvgxQcem9oYXJAbGlu dXguaWJtLmNvbQAKCRDLwZzRsCrn5dC1AP9Byw49KACrNM8vvic/MTB4i3azMbFU ZNbcXgj9xRwyngD/fjwktpYUwEvgMIDybIu0Tr+CXUwoI8vrmPZpsvkeUwI= =eSwF -----END PGP SIGNATURE----- Merge tag 'integrity-v7.3' of 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 |
||
|
|
cbad8981fa |
Patches for v7.3
-----BEGIN PGP SIGNATURE----- iQJLBAABCAA1FiEEC+9tH1YyUwIQzUIeOKUVfIxDyBEFAmp+ClEXHGNhc2V5QHNj aGF1Zmxlci1jYS5jb20ACgkQOKUVfIxDyBG85g/9GPmiweiDUjMq3dlrAzJ4vi4f h9+Eu4y7Relg7wMvXnOuc3ZB/QxGKSHBlzxwfCIoqtAC9wFbbqP4hhJ0c6yladCL M0fmJT/JRZcIZdHzwu2G5skNxwtms9sFyyBi4Pq6YkA/fszHig5vZJquVIP0mIZV DF3dsOC2fw8g/kSe4OcZF+0qZABaY/LHrZTS/Mit9GQa8AVS0CLFubrbE2pOSQJ5 TwLXtqOZQVWq814kzFmdOomQNdzR35HH30EXgan5Q06oN25i6YbL1RZkOXKhLn4t eGDT33wKiEt9M7x0R4MZOFnkAKgs8hDtBvBd1/lvkvU7rZkG7FWH+weh9CiFtyoT LkbPxVmdFI1IZCOaxqB6Pl/ZKy7QQbm0Hy3TEL7vizhSbh5qOZhjwTjESvOQgGA5 ynUkJIuECYfyXyFJSiA1QRGR9lOwgXWa8qJYl71GrTCgGu/CDraDARkOLgM+afih WU4TZsTlwOJSP0UhfmhAzMxNs7K2YjYj2tvDhV0aKMz7WLLd+ivJIYNsupfftqO6 iCWjshncvF4NrULumErLcm9BBy9SjUH4JansLSfh52TI4XfKP9sEQSkCCLbOK5J4 uGAotKWUIyAL+cfOrMCmViFMopCe7LcrDFsF5ocT84wRDT5K8ljnMm8lpKzrfrh2 N1OA5EHi88OfmVnules= =ucTi -----END PGP SIGNATURE----- Merge tag 'Smack-for-7.3' of https://github.com/cschaufler/smack-next 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 |
||
|
|
09005a6398 |
lsm/stable-7.3 PR 20260814
-----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmp/iWkUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXPvbQ/8DT62doPc0ECTXQXcTNjBOddjNspB pk2mK238UQP50aU7/su4RdgmGG+spVoPc7oqeavnm2J+c552t0eHI61itYMe7nkY uOIjShLN93g9pjG4IqhmCDvGTpsQp9Oiec5F/6C++7OUT5oUqm/faXAZtwFLFgmx pTNf91w+u5s3DJjqG5zqEdteRrQMzDNozdq4YbNkzeIiofsUJvq6IJ6rV66kyOa/ zk2hC6zI3mL0Vuin3WdxKqd1mD7mhYWxjl2nt/0TTIRMKmycxovlvbfADXXi2hlp 4tALFgbEmeOgXr7HWvOqClNZ002/gG84Ty2F/8D/p0EGlzOc0Ga/q1dSAM/JJ5RZ bArXY3qgioU4/zOp998kXIYgRV3i6ZBBEzqTavcVtgCtNTgc2MH+KftD9HJaVjx8 keRClwB85r72mNqKVcTVgQ8MJvA+Fq03JHc/JH3npv2tSPELK4V4vkW0nCGQsLXV /oX87E9/Wh6wWchvUTYToX5j6eNRUjD8xQzIAbPWTilusPcIp9pW58I6gaDKAu6A dNox9I064JfLK+LEmn8Le8AatTT0g/mj1wTD0KeRfo0zKyjSYoT0ECnXBeAfg9QI Vr6ZTXPM0fMpKEHqJvYLJAqVbm3kJKZqxr1z4nmz14elms1SmwdmOSq66Qm8fRCS P5fGVxFzNbDVZvs= =eToU -----END PGP SIGNATURE----- Merge tag 'lsm-pr-20260814' of 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 |
||
|
|
4253eb09d2 |
selinux/stable-7.3 PR 20260814
-----BEGIN PGP SIGNATURE----- iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmp/iXIUHHBhdWxAcGF1 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXN+Wg/7B8/owEGutN2OwRQKfo/qIjYsCp2B a4mhT/K5JTVYYTr5PsbVb8OkRrIdpZhLTOGzRN7e16o7HrV77szJ2zeiizlHp7q2 t7iuwWtLbF9q2qlHEg2/p+VZvfq82bBPgLHwzfuXh+2TMVUHWHw//gw90Aqjg7np BNxagAdTM5zodv4OqNnwUkve9Y90VTBD3pbsFrn15lgh3efovg9ya2Xy/sJlSVQG 8yGJtFxj+CodsLBW76G3/jjOiTC1/XMGacZYgHWIaZsxr2EHjmCZdU6jdoZxqXOi iG45yaf/HOIMnuSoVq6R5PG4I3paxa9Po75z3NWBdxQQqHOiAguYG8pHdxPxrDv2 QOkyHai04/x9XCqiyA91TflTflGZOdio5M9YHbUv2FjNyMsenEdjuT1prUpsLZ/Y 1dl0iLDuotS3l/NRtm0Yc+epl8N6GeCB0UCJK1AHSAZJt+twOy0jJfRvUIVfpw9B cQgkyegEKlm7PX2nzre/A727H6CrnZsneYjQeE1/+0szmRDKfYEOghSuw3FmKyqr 1gAm851G27ySF+75h9SiNLmdJgkHeOGa5pxO+qa2ZtZFXfK9ie3317i2t7Aoaiec 6dfHTF5JsfdHcqjESuD+ibVbPpvGC4SFkWd3RbogiNhREbt4Sy2pw3j4WxUND9bv f1hVBz4/SyV9M+4= =6vH+ -----END PGP SIGNATURE----- Merge tag 'selinux-pr-20260814' of 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 |
||
|
|
bb91730f16
|
landlock: Add tracepoints for ptrace and scope denials
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> |
||
|
|
01ce260f5c
|
landlock: Add landlock_deny_access_fs and landlock_deny_access_net
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> |
||
|
|
3f1f106e4c
|
landlock: Add tracepoints for rule checking
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> |
||
|
|
132d84b16b
|
landlock: Add landlock_enforce_domain tracepoint
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> |
||
|
|
67567f03a4
|
landlock: Add create_domain and free_domain tracepoints
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> |
||
|
|
63747c9477
|
landlock: Add landlock_add_rule_fs and landlock_add_rule_net tracepoints
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> |
||
|
|
b4540a72be
|
landlock: Add create_ruleset and free_ruleset tracepoints
Add the first Landlock tracepoints, for ruleset lifecycle: landlock_create_ruleset fires from the landlock_create_ruleset() syscall handler, and landlock_free_ruleset fires in free_ruleset() before the ruleset is freed. These tracepoints, and the ones added by the following commits, share a common design. Rather than one polymorphic event distinguished by a status field (as audit uses a shared record type with a "status=" field), each lifecycle transition and denial type gets its own event with a type-safe TP_PROTO, giving precise ftrace filtering by event name and type-safe eBPF access. TP_PROTO passes the object pointer and the fields are read from it in TP_fast_assign, so an eBPF program reads the full object state (rules, access masks, hierarchy) via BTF from a single pointer rather than from the flattened TP_STRUCT__entry fields. The whole cost is paid only when a tracer is attached; the static branch is not taken otherwise. Trace fields carry the bare access-right and scope names (read_file), reusing the audit name tables; audit prepends the category (fs.read_file), which the trace event name already conveys. The trace header's DOC comment documents the consistency and locking guarantees these events share. create_ruleset needs no lock because the ruleset is not yet shared (its file descriptor is not yet installed). The deallocation events use the "free_" prefix, not "drop_", because they fire when the object is actually freed. Add trace.c, built for CONFIG_TRACEPOINTS, which defines CREATE_TRACE_POINTS, and extend CONFIG_SECURITY_LANDLOCK_LOG to also be selected by CONFIG_TRACEPOINTS so the common log framework is available to a tracepoints-only build. Add an id field to struct landlock_ruleset, gated on CONFIG_TRACEPOINTS and assigned from landlock_get_id_range() at creation. Only the tracepoints consume it (audit identifies domains, not rulesets), so it does not exist in an audit-only build. The Landlock ID is a stable u64 that names the ruleset across the trace stream and uses the same scheme as audit, so a ruleset can be correlated between trace and 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-8-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
bc62ec6034
|
landlock: Consolidate access-right and scope names in a shared header
Audit formats denial records with per-right name strings. A following
commit adds trace events that print the same access and scope masks with
__print_flags() and need the same names, but a trace event header cannot
include Landlock-internal headers, so the names cannot be shared from
the logging unit.
Define the filesystem, network, and scope names once, as the
_LANDLOCK_ACCESS_FS_NAMES, _LANDLOCK_ACCESS_NET_NAMES, and
_LANDLOCK_SCOPE_NAMES lists in the public Landlock header. Each entry
is a _LANDLOCK_NAME_ENTRY() the consumer expands: audit maps it to a
"[bit] = name" array slot for an O(1) lookup, the trace events map it to
a __print_flags() { mask, name } pair. The bit value comes only from
the LANDLOCK_* UAPI constant each entry references, so every bit-to-name
mapping has a single source and does not depend on entry order.
The shared names are unprefixed; blocker_prefix() prepends the
fs./net./scope. category for audit records, so the scope names move from
inline literals to the shared table too. Audit records are unchanged.
No functional change.
Cc: Günther Noack <gnoack@google.com>
Cc: Tingmao Wang <m@maowtm.org>
Link: https://patch.msgid.link/20260811094338.288094-7-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
|
||
|
|
69ca5782f8
|
landlock: Decouple the per-denial logging decision from CONFIG_AUDIT
Until now, whether a denial is logged was decided inside landlock_audit_denial(): a per-execution flag check (log_same_exec or log_new_exec, selected by the credential's domain_exec bitmask), preceded by a LANDLOCK_LOG_DISABLED early return in landlock_log_denial() for domains an ancestor fully quieted. Factor that decision into a single is_denial_logged() helper called once by landlock_log_denial(), and pass its result to landlock_audit_denial() as a "logged" boolean. A following commit passes the same boolean to the deny tracepoints, so audit and tracing share one decision that stays correct as new log state is added, and a tracepoints-only build (CONFIG_AUDIT=n) computes it identically. Computing the logged verdict once in the shared helper makes audit and tracing apply identical filtering, so they cannot report different logged= values for the same denial as log controls grow. Move the LANDLOCK_LOG_DISABLED gate out of landlock_log_denial() into the decision so num_denials counts every denial, including those a domain quiets. This was previously masked: the only reader of num_denials is the audit "domain deallocated" record, emitted only for domains that reached LANDLOCK_LOG_RECORDED; a fully quieted domain never records, so its undercount was never observable. A following commit adds a free_domain tracepoint that reports num_denials, which needs the full count. This is not a functional change for audit: the logged decision and the audit_enabled gate are preserved, so the emitted records are identical. Cc: Günther Noack <gnoack@google.com> Link: https://patch.msgid.link/20260811094338.288094-6-mic@digikod.net Reviewed-by: Tingmao Wang <m@maowtm.org> [mic: Update copyright] Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
e761a88ced
|
landlock: Split denial logging from audit into common framework
Tracepoint emission requires the denial framework (layer identification, request validation) without depending on CONFIG_AUDIT. Separate the denial logging infrastructure from the audit-specific code by introducing a common log framework. Create CONFIG_SECURITY_LANDLOCK_LOG, enabled by default when CONFIG_AUDIT is set; a following commit extends it to CONFIG_TRACEPOINTS when the first tracepoint consumer is added. Move the common framework (the request types, the layer identification and request validation, and the landlock_log_denial() and landlock_log_free_domain() entry points) into log.c and log.h, and keep the audit-specific record formatting in audit.c. log.o is built for CONFIG_SECURITY_LANDLOCK_LOG and audit.o for CONFIG_AUDIT, so the common framework is available to a tracepoints-only build. The entry points dispatch to no-op static inline audit stubs without CONFIG_AUDIT, so the call sites stay unconditional. Rename the former landlock_log_drop_domain() to landlock_log_free_domain() to match the landlock_free_domain tracepoint added in a following commit. landlock_log_denial() counts denials even without audit, so its declaration and no-op stub are guarded by CONFIG_SECURITY_LANDLOCK_LOG, not CONFIG_AUDIT; a CONFIG_AUDIT guard would expose the stub and clash with log.c's definition in a tracepoints-only build. Widen the ID allocation (id.o and the landlock_init_id() / landlock_get_id_range() declarations) and the log-state representation (the domain_exec and log_subdomains_off credential fields, the landlock_hierarchy log fields, and the code that maintains them) from CONFIG_AUDIT to CONFIG_SECURITY_LANDLOCK_LOG, so each field and its writer share one guard and are available to tracing without audit support. Widen the denial-path state that feeds the per-denial logging decision the same way, so the "logged" verdict is computed identically whether or not CONFIG_AUDIT is set. Widening fown_layer is what keeps the file-owner-signal path valid without audit: otherwise hook_file_send_sigiotask() would leave layer_plus_one at zero, tripping the is_valid_request() canary and dropping the LANDLOCK_SCOPE_SIGNAL denial from tracing. The ruleset-level quiet_masks stays on no CONFIG guard: it is builder state validated and stored from user input, kept available so LANDLOCK_ADD_RULE_QUIET flags are accepted and ignored, not rejected, when CONFIG_SECURITY_LANDLOCK_LOG is disabled. Cc: Günther Noack <gnoack@google.com> Link: https://patch.msgid.link/20260811094338.288094-5-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
3841160416
|
landlock: Split struct landlock_domain from struct landlock_ruleset
Switch all domain users to the new struct landlock_domain type introduced by a previous commit, eliminating the conflation between mutable rulesets and immutable domains. landlock_merge_ruleset() now returns and allocates a struct landlock_domain, and the merge and inherit helpers move next to it; the former static insert_rule() is exported as landlock_store_rule() for its new caller across the translation-unit boundary. The merge destination is now a private struct landlock_domain still under construction (owned by the calling thread, not yet shared), so the merge and inherit helpers lock only the source ruleset: the previous lock of both destination and source collapses to a single mutex_lock(&src->lock). Rename the per-layer access-mask field from access_masks to handled_masks, naming it by the role it plays (the rights each layer handles) rather than by its type, paralleling the struct access_masks quiet_masks field. Drop the now domain-only fields (hierarchy, work_free, num_layers) from struct landlock_ruleset. The new struct landlock_domain field in cred.h pulls in domain.h, which includes audit.h, which previously included cred.h, forming an include cycle. Break it by having audit.h forward-declare the struct landlock_cred_security and struct landlock_hierarchy it uses instead of including cred.h. Cc: Günther Noack <gnoack@google.com> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-4-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
2bbba0905a
|
landlock: Move domain query functions to domain.c
Grouping domain-specific code in one compilation unit reduces coupling between domain and ruleset implementations. Move the access-check functions that only operate on a domain (rule lookup, layer unmasking, layer-mask init, access-mask union) from ruleset.[ch] to domain.[ch]. They evaluate whether a domain grants a requested access during the pathwalk and network checks and do not modify the domain. The merge and inherit chain stays in ruleset.c for now because it calls the static create_ruleset() allocator; a following commit moves it once the domain type switch eliminates that dependency. No behavioral change. The functions move with unchanged signatures and bodies. Cc: Günther Noack <gnoack@google.com> Cc: Tingmao Wang <m@maowtm.org> Link: https://patch.msgid.link/20260811094338.288094-3-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
e76ef456bb
|
landlock: Prepare ruleset and domain type split
Rulesets and domains serve fundamentally different purposes: a ruleset is mutable and user-facing, created by landlock_create_ruleset(), while a domain is immutable after construction and enforced on tasks via landlock_restrict_self(). Today both are represented by struct landlock_ruleset, which conflates mutable and immutable state in a single type: the lock field is unused by domains, the hierarchy field is unused by rulesets, and lifecycle functions must handle both cases. Prepare for a clean type split by introducing two new structures: - struct landlock_rules: the red-black tree roots and rule count, shared by both rulesets and domains. Decoupling rule storage from the domain API lets the backing data structure change independently (e.g. to a hash table, cf. [1]). - struct landlock_domain: the immutable domain enforced on tasks, with no lock field because its rules and access masks are fixed once construction completes. The name reflects the role, not the internal data structure. Add the domain lifecycle helpers (landlock_get_domain(), landlock_put_domain(), landlock_put_domain_deferred()) and move domain.o from landlock-$(CONFIG_AUDIT) to landlock-y, because these are needed unconditionally, not just for audit logging. No behavioral change. The new types and lifecycle functions are not yet used by any caller. Cc: Günther Noack <gnoack@google.com> Link: https://patch.msgid.link/20250523165741.693976-1-mic@digikod.net [1] Link: https://patch.msgid.link/20260811094338.288094-2-mic@digikod.net Reviewed-by: Tingmao Wang <m@maowtm.org> [mic: Update copyright] Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
4ec11f14d1 |
apparmor: fix deadlock in complain-mode change_hat
The use of change_hat when in complain mode can cause a deadlock when the hat doesn't exist and a new learning profile is created for the missing profile. This is because change_hat() has taken the lock to search the hat list and creating the new learning profile needs to take the lock to add it to the list. From the bug report: Originally found in 7.0.0 in LTS ubuntu 26.04 with pam_apparmor + su in complain mode set to change hats. Then verified in newest available vanilla kernel I've compiled to see if still present: 7.2-rc7 vanilla -> affected checked also some other kernels: 6.18.44 vanilla -> affected 6.12.95 with debian patches -> unaffected On systems without bug (for example 6.12.95 debian) it just prints: aa_change_hat rc=0 On systems with bug, the executable always hangs, prints nothing and becomes unkillable. (And once stuck this way, it will cause any further hat changes to also cause the changing process to get stuck) Then in syslog you can find hint about cause: kernel: INFO: task hat:3409 blocked for more than 483 seconds. kernel: Not tainted 7.2.0-rc7 #1 kernel: "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message. kernel: task:hat state:D stack:0 pid:3409 tgid:3409 ppid:2605 task_flags:0x400000 flags:0x00080800 kernel: Call Trace: kernel: <TASK> kernel: __schedule+0x48f/0xfe0 kernel: schedule+0x27/0xa0 kernel: schedule_preempt_disabled+0x15/0x30 kernel: __mutex_lock.constprop.0+0x569/0xa10 kernel: aa_new_learning_profile+0x15f/0x210 kernel: build_change_hat+0x19f/0x3b0 kernel: change_hat.isra.0+0x5dd/0xd60 kernel: aa_change_hat+0x2f3/0x710 kernel: aa_setprocattr_changehat+0x121/0x1f0 kernel: do_setattr+0x28c/0x340 kernel: apparmor_setselfattr+0x20/0x50 kernel: security_setselfattr+0xf6/0x110 kernel: __x64_sys_lsm_set_self_attr+0x53/0x90 kernel: do_syscall_64+0xdd/0x5e0 kernel: ? __mod_memcg_lruvec_state+0xfd/0x260 kernel: ? lruvec_stat_mod_folio+0x8d/0xd0 kernel: ? __folio_mod_stat+0x2d/0x90 kernel: ? map_anon_folio_pte_nopf+0xd1/0x1f0 kernel: ? do_anonymous_page+0x184/0xa10 kernel: ? __handle_mm_fault+0x805/0x870 kernel: ? count_memcg_events+0xef/0x230 kernel: ? handle_mm_fault+0x1f0/0x2f0 kernel: ? do_user_addr_fault+0x2bb/0x7b0 kernel: ? do_syscall_64+0x94/0x5e0 kernel: ? exc_page_fault+0x75/0x160 kernel: entry_SYSCALL_64_after_hwframe+0x76/0x7e kernel: RIP: 0033:0x7f815e134c8d kernel: RSP: 002b:00007fff6df94ea8 EFLAGS: 00000246 ORIG_RAX: 00000000000001cc kernel: RAX: ffffffffffffffda RBX: 0000556d8c81d040 RCX: 00007f815e134c8d kernel: RDX: 0000000000000046 RSI: 0000556d8c81d040 RDI: 0000000000000064 kernel: RBP: 00007fff6df94ef0 R08: 00007f815e212ac8 R09: 000000000000000c kernel: R10: 0000000000000000 R11: 0000000000000246 R12: 0000556d8c81d010 kernel: R13: 0000000000000026 R14: 0000000000000046 R15: 0000000000000064 kernel: </TASK> kernel: INFO: task hat:3409 is blocked on a mutex likely owned by task hat:3409. To fix the issue, lift the locking out of the core of aa_new_learning_profile(), introduce a wrapper function that takes the lock where needed, and have build_change_hat() call the core function that no longer takes the lock. In addition fix 4 other issues introduced by commit |
||
|
|
6887c03bf2
|
landlock: Add LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS
Add a landlock_restrict_self(2) flag to set the no_new_privs attribute of the calling thread only after enforcement of the ruleset: no_new_privs is set if and only if the call succeeds. This removes the need for a prior prctl(2) PR_SET_NO_NEW_PRIVS call and guarantees that a failed enforcement leaves the attribute unchanged. Because no_new_privs is set by the call itself, the no_new_privs / CAP_SYS_ADMIN requirement of landlock_restrict_self(2) is fulfilled by construction, and the related EPERM check is skipped. Unlike LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF, this flag always requires a valid ruleset: with a ruleset_fd of -1, such a call would be nothing more than a Landlock-flavored prctl(2) PR_SET_NO_NEW_PRIVS, and there is no valid use case for setting no_new_privs (possibly with LANDLOCK_RESTRICT_SELF_TSYNC) without also enforcing Landlock restrictions. Rejecting these calls also keeps the option of giving them a meaning later. The attribute is only set past the last point of failure, just before committing the new credentials. When combined with LANDLOCK_RESTRICT_SELF_TSYNC, no_new_privs is set on the sibling threads as well, in their commit phase, with the same ordering. Bump the Landlock ABI version to 11, and include the minimal related test changes to keep the tests bisectable. Cc: Mickaël Salaün <mic@digikod.net> Signed-off-by: Justin Suess <utilityemal77@gmail.com> Link: https://patch.msgid.link/20260809212459.2427878-1-utilityemal77@gmail.com Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
c2fe8b60b8
|
landlock: Check landlock_restrict_self(2)'s flags before privileges
landlock_restrict_self(2) currently checks the no_new_privs / CAP_SYS_ADMIN requirement before validating the flags argument. An unprivileged caller without no_new_privs thus gets EPERM even when the passed flags are invalid, hiding the EINVAL error. Move the no_new_privs / CAP_SYS_ADMIN check just after the flags check so that malformed calls consistently error out with EINVAL whatever the caller's privileges, the same way seccomp(2) validates its flags before checking no_new_privs. Update the restrict_self_checks_ordering test accordingly. Cc: Mickaël Salaün <mic@digikod.net> Signed-off-by: Justin Suess <utilityemal77@gmail.com> Link: https://patch.msgid.link/20260809154544.1253100-2-utilityemal77@gmail.com Signed-off-by: Mickaël Salaün <mic@digikod.net> |
||
|
|
672fa082d4
|
landlock: Require LANDLOCK_ACCESS_FS_MAKE_REG for whiteout creation
Whiteout objects are used in the upper layer of an OverlayFS to indicate that the file with this name does not exist in the unified view, even if it is present in one of the lower layer file systems. For the userspace implementations of OverlayFS (fuse-overlayfs), whiteout objects can be created from userspace as well: * mknod(2) with S_IFCHR and makedev(0, 0) * renameat2(2) with RENAME_WHITEOUT, creating the whiteout in the old place of the moved file. This commit guards whiteout creation in both of these cases with LANDLOCK_ACCESS_FS_MAKE_REG. Whiteout objects are *not* considered character devices and are not bound to a driver. LANDLOCK_ACCESS_FS_MAKE_REG describes the same permission class as a whiteout object: creating one is the only S_IFCHR creation that the VFS exempts from CAP_MKNOD, so it is as unprivileged as creating a regular file, while LANDLOCK_ACCESS_FS_MAKE_CHAR and LANDLOCK_ACCESS_FS_MAKE_BLOCK keep meaning the creation of devices that expose a kernel interface [1]. For the mknod(2) case, introduce a Landlock erratum. The creation of whiteout objects through mknod(2) was previously guarded using LANDLOCK_ACCESS_FS_MAKE_CHAR, and it is now guarded using LANDLOCK_ACCESS_FS_MAKE_REG. For the renameat2(2) case, fix a bug: Before this commit, renameat2(2) with RENAME_WHITEOUT would create a directory entry even when all LANDLOCK_ACCESS_FS_MAKE_* rights were denied. This does not affect normal renames within layered OverlayFS mounts: When doing a regular rename() on a mounted fuse-overlayfs, it is the fuse-overlayfs daemon that exercises renameat2() with RENAME_WHITEOUT, and only the Landlock domain of that daemon is checked there. Suggested-by: Christian Brauner <brauner@kernel.org> Suggested-by: Mickaël Salaün <mic@digikod.net> Cc: stable@vger.kernel.org Fixes: |