Commit Graph

7233 Commits

Author SHA1 Message Date
Linus Torvalds
60aba79a50 * Bug Fixes
- Leaks
     - fix a leak on a rejected string table entry
     - fix refcount leak in aa_get_newest_profile()
     - fix profile leak when a policy load fails
     - remove fs entries created by a failed policy load
     - on failed load ensure profile files are removed before parent
     - Fix namespace reference leak in __aa_find_or_create_ns()
 
   - Use after free/double free
     - fix a use-after-free in aa_lookupn_ns()
     - avoid potential double free when remapping DFA tables
 
   - Bounds checking by-passes
     - apparmor: fix table_size() integer overflow on 32 bit
     - apparmor: check accept index + 1 is in bounds
 
   - Mediation fixes
     - Fix AF_UNSPEC mediation
       - check address length before reading AF_UNSPEC bind address
       - mediate AF_UNSPEC socket disconnects
     - Fix sctp connect/bind by-passess
       - advertise that sctp is being mediated
       - fix check SCTP bind, and connect permission checks
       - check connect permission for SCTP
 
     - incorrect state machine traversal
       -  convert duplicated dfa transitions to match_char()
 
     - locking issues
       - don't revalidate inherited files under files->file_lock
       - fix uninitialized variable warning in aa_inherit_files
 
     - Bad dereferences
       - fix NULL ctx->peer derefs in unix socket ctx updates
 
   - unnecessary warnings
     - remove unconfined_profile() check in inet socket mediation
 
   - Kernel Doc
     - Fix the return value in split_token_from_name() kernel-doc
 
   - Misc
     - fix query_data() output overlapping the lookup key
     - report a label allocation failure as -ENOMEM
 -----BEGIN PGP SIGNATURE-----
 
 iQIzBAABCgAdFiEE7cSDD705q2rFEEf7BS82cBjVw9gFAmrkwqUACgkQBS82cBjV
 w9gTaA//a0x0mMoQxt1/sP6XDC4ud7ywcPqp9veZpV6r0Cek1pYrtSGfoi/uhAau
 3gHu/2wR/otchekkK01pYbvhiJysSKCIui/QRBM+gEgBvGzpwDC1IyqhW1vdjGIQ
 T4eNgmEWVvK1wMDfZXBLDGHuEiE/XWPxtMFWbd1ZUWD9+jMG2ZOtkOlUgSg/ViJY
 V/5+UjKD8VlrmTU6HVTnLl3R39BXCdSfHkHVR8/O7+CDkOyAx9XLj7r7sYhenUIQ
 kl09aNE3pTrMu0JEPP7tWl/pEJMssYctR/Q5Q+9hrNRvEH8K/tUzEMaRlxv5rxu1
 Z4tfwRMNuNhGJxRABp8un8vcuPtsnaKEnp1zbzkhNZj/fGsF2LySEapXPCuiq1Sh
 dlQc3lOPIHYE2Q71IS/vZ9+1pZ4N+IreuKtPIVnxPQq5RYWHRp7drbXfsHpCaUqt
 PXaLXENW8eF7v7y+UJEIztyOI4wyFOM3BpblFrJxSHArcHzI/StPnMZv10yx5PqX
 kgwymScmi2hyhehrHqSzWbW2GmJLwvF1un7Lk/GRNrvWytAs/1hJIr6N7/ov/NEu
 NVDCi3lN+M2e2c0/dWuwg/Kn1nEo7vVMRNlbdXJHXfxDDZgaZQCGagibVcgmPk9i
 KvmVQtlnUvf4LiABC/efDvGkxMeR3+JHjVrxS7s1DIKy1fFSIWU=
 =MAYC
 -----END PGP SIGNATURE-----

Merge tag 'apparmor-pr-2026-10-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor

Pull AppArmor fixes from John Johansen:
 "Leaks:
   - fix a leak on a rejected string table entry
   - fix refcount leak in aa_get_newest_profile()
   - fix profile leak when a policy load fails
   - remove fs entries created by a failed policy load
   - on failed load ensure profile files are removed before parent
   - Fix namespace reference leak in __aa_find_or_create_ns()

  Use after free/double free:
   - fix a use-after-free in aa_lookupn_ns()
   - avoid potential double free when remapping DFA tables

  Bounds checking by-passes:
   - fix table_size() integer overflow on 32 bit
   - check accept index + 1 is in bounds

  Mediation fixes:
   - Fix AF_UNSPEC mediation
      - check address length before reading AF_UNSPEC bind address
      - mediate AF_UNSPEC socket disconnects
   - Fix sctp connect/bind by-passess
      - advertise that sctp is being mediated
      - fix check SCTP bind, and connect permission checks
      - check connect permission for SCTP
   - incorrect state machine traversal
      -  convert duplicated dfa transitions to match_char()
   - locking issues
      - don't revalidate inherited files under files->file_lock
      - fix uninitialized variable warning in aa_inherit_files
   - Bad dereferences
      - fix NULL ctx->peer derefs in unix socket ctx updates

  Unnecessary warnings:
   - remove unconfined_profile() check in inet socket mediation

  Kernel Doc:
   - Fix the return value in split_token_from_name() kernel-doc

  Misc:
   - fix query_data() output overlapping the lookup key
   - report a label allocation failure as -ENOMEM"

* tag 'apparmor-pr-2026-10-29' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (23 commits)
  apparmor: fix uninitialized variable warning in aa_inherit_files
  apparmor: fix profile leak when a policy load fails
  apparmor: on failed load ensure profile files are removed before parent
  apparmor: remove fs entries created by a failed policy load
  apparmor: fix query_data() output overlapping the lookup key
  apparmor: advertise that sctp is being mediated
  apparmor: fix check SCTP bind, and connect permission checks
  apparmor: check connect permission for SCTP
  apparmor: fix a use-after-free in aa_lookupn_ns()
  apparmor: Fix namespace reference leak in __aa_find_or_create_ns()
  apparmor: check accept index + 1 is in bounds
  apparmor: Fix the return value in split_token_from_name() kernel-doc
  apparmor: convert duplicated dfa transitions to match_char()
  apparmor: fix table_size() integer overflow on 32 bit
  apparmor: avoid potential double free when remapping DFA tables
  apparmor: report a label allocation failure as -ENOMEM
  apparmor: fix a leak on a rejected string table entry
  apparmor: remove unconfined_profile() check in inet socket mediation
  apparmor: fix refcount leak in aa_get_newest_profile()
  apparmor: check address length before reading AF_UNSPEC bind address
  ...
2026-10-30 21:50:13 -07:00
John Johansen
ed35bbe7d0 apparmor: fix uninitialized variable warning in aa_inherit_files
Fix the following warning

All warnings (new ones prefixed by >>):

>> security/apparmor/file.c:737:53: warning: variable 'file' is uninitialized when used here [-Wuninitialized]
     737 |                 int error = aa_file_perm(OP_INHERIT, cred, label, file,
         |                                                                   ^~~~
   security/apparmor/file.c:724:36: note: initialize the variable 'file' to silence this warning
     724 |         struct file *devnull = NULL, *file;
         |                                           ^
         |                                            = NULL
   1 warning generated.

vim +/file +737 security/apparmor/file.c

   719
   720	/* based on selinux's flush_unauthorized_files */
   721	void aa_inherit_files(const struct cred *cred, struct files_struct *files)
   722	{
   723		struct aa_label *label = aa_get_newest_cred_label(cred);
   724		struct file *devnull = NULL, *file;
   725		bool devnull_tried = false;
   726		unsigned int n = 0;
   727
   728		revalidate_tty(cred, label);
   729
   730		/*
   731		 * Revalidate access to inherited open files. Each file is
   732		 * revalidated holding only a reference to it, with no locks
   733		 * held, as revalidation may sleep (e.g. unix socket mediation
   734		 * dropping path refs, or allocating path buffers).
   735		 */
   736		while ((n = iterate_fd(files, n, get_next_file, &file)) != 0) {
 > 737			int error = aa_file_perm(OP_INHERIT, cred, label, file,

Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202610292346.ehqNujiE-lkp@intel.com/
Fixes: a913281f60 ("apparmor: don't revalidate inherited files under files->file_lock")
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 17:02:50 -07:00
Georgia Garcia
ce94927fa4 apparmor: fix profile leak when a policy load fails
The error paths of aa_replace_profiles() and aa_unpack() do not break
the refcount cycle between label and proxy. They just aa_put_profile()
the new profiles, which drops the label refcount from 2 to 1, and the
proxy keeps the profile alive. Every failed atomic policy load
(e.g. "profile can not be replaced", or a later profile in the blob
failing to unpack) leaks every new profile in the set, along with its
proxy, rules and its loaddata reference.

The leak is usually not visible from userspace, because the raw_data
directory for a failed load is not created, but it becomes visible
when the blob is deduplicated onto an existing loaddata, which then
keeps its policy/raw_data/<rev> directory forever.

Add aa_put_unpublished_profile(), which drops the profile's own proxy
before putting the profile, and use it on those error paths. The
proxy of an unpacked profile is always freshly allocated and not
referenced by anything else before the profile is published, so
putting it is safe.

Fixes: 637f688dc3 ("apparmor: switch from profiles to using labels on contexts")
Cc: stable@vger.kernel.org
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 10:44:18 -07:00
John Johansen
97ba44a2aa apparmor: on failed load ensure profile files are removed before parent
The load interface does not guarantee the order profiles are loaded.
When a parent is loaded after its child, and the load fails, the
current code will issue a warning, and leak a dentry.

For the loaded set of profiles, ensure that on failure list is ordered
is traversed in reverse so any children processed after their parent
is freed first. We do not need to deal with the cases where the
children are processed before their parent, because either a parent
outside the list already exists or a dummy parent outside of the list
is created, and the list walk will not put those parents before their
children.

Fixes: 6ec46f8f19 ("apparmor: remove fs entries created by a failed policy load")
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 10:40:00 -07:00
Georgia Garcia
6ec46f8f19 apparmor: remove fs entries created by a failed policy load
aa_replace_profiles() creates the raw_data/<rev> directory for the
loaddata and the profile directories for new profiles before the last
checks that can fail. When one of those checks fails, the fail path
releases the ns lock without removing what this load created.

The raw_data directory is named after the current ns revision, and the
revision is only bumped by a successful load. The stale directory is
only removed once the loaddata's last profile reference is dropped, from
a workqueue. Until then, every load fails to create raw_data/<rev> with
-EEXIST. If the new profiles are never freed, which is the case when
their dents are left behind pinning the proxy, that never happens and no
policy can be loaded until reboot.

While still holding the ns lock in the fail path, remove the profile
directories of the new profiles and, if this load created it, the
raw_data directory.

Fixes: 5d5182cae4 ("apparmor: move to per loaddata files, instead of replicating in profiles")
Cc: stable@vger.kernel.org
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 09:25:25 -07:00
Cen Zhang (Microsoft)
d308440013 apparmor: fix query_data() output overlapping the lookup key
In query_data(), buf and query point into the same multi_transaction
buffer: buf at the start, query a few bytes in, and the lookup key
right after the label string that query points to. Reusing the buffer
is by design and is safe as long as the query is fully parsed before
buf is written to, but the key is not: it is dereferenced on every
iteration of label_for_each_confined(), after output has already been
written. So when the label has more than one profile with a data
table, the data of the first matching profile is written to buf while
the key is still needed, and overwrites it if the data is large enough.
The later lookups then run on a corrupted key. Besides, if the data has
no NUL byte from the key's position to the end of the allocation,
strhash() -> strlen() -> jhash() reads past the 4096-byte slab object,
triggering an out-of-bound read:

  BUG: KASAN: slab-out-of-bounds in jhash+0x595/0x5e0
  Read of size 1 at addr ff1100001159d000 by task exploit/155
  CPU: 0 UID: 1000 PID: 155 Comm: exploit Not tainted 7.3.0-rc7 #1
  Call Trace:
   jhash+0x595/0x5e0
   aa_write_access+0x880/0x1400
   vfs_write+0x26f/0xd20
   ksys_write+0x115/0x210

Writing to the .access file is unprivileged (0666), but triggering this
requires loaded profiles that carry a data table, which needs
CAP_MAC_ADMIN and is not the case on default distribution policies.

Fix by copying the key with kstrdup() before writing any output to buf,
so the key stays valid across all loop iterations regardless of what
gets written to the overlapping buffer.

Fixes: 317d9a054e ("apparmor: update query interface to support label queries")
Cc: stable@vger.kernel.org # v4.13+
Cc: Francis Perron <francis@akrites.dev>
Reported-by: AutonomousCodeSecurity@microsoft.com
Signed-off-by: Cen Zhang (Microsoft) <cenzhang@linux.microsoft.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 09:25:25 -07:00
John Johansen
35b8ab3f36 apparmor: advertise that sctp is being mediated
Enable the test harness to detect that the kernel should be properly
mediating sctp.

Fixes: 7a82f9a064 ("apparmor: fix check SCTP bind, and connect permission checks")
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 09:24:51 -07:00
John Johansen
7a82f9a064 apparmor: fix check SCTP bind, and connect permission checks
SCTP mediation of bind is not being checked correctly because bind
permission needs to be checked in the sctp_bind_connect() hook.

Require for bind permissions when CTP_SET_PEER_PRIMARY_ADDR, and
SCTP_SOCKOPT_BINDX_ADD are asked for.

The peer initialized ASCONF cases (SCTP_PARAM_ADD_IP and
SCTP_PARAM_SET_PRIMARY) are processed in softirq context and are not
mediated atm. SCTP_PRIMATEY_ADDR, and SCTP_SET_PEER_PRIMARY_ADDR only
select among address already in the association.

Fixes: 56974a6fcf ("apparmor: add base infastructure for socket mediation")
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 09:03:55 -07:00
Jérémy Jean
2f764c08bb apparmor: check connect permission for SCTP
SCTP can start an association through sendmsg() or CONNECTX. These paths
call the SCTP-specific sctp_bind_connect hook instead of the normal socket
connect hook, but AppArmor does not register it. As a result, a profile can
deny connect and allow send or setopt, yet a task can still create an SCTP
association.

Register the SCTP hook. Ask for connect permission when SENDMSG_CONNECT
or CONNECTX creates an association.

Fixes: 56974a6fcf ("apparmor: add base infastructure for socket mediation")
Assisted-by: LLM
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Binbin Deng
f292873ceb apparmor: fix a use-after-free in aa_lookupn_ns()
aa_lookupn_ns() takes a reference on the namespace it finds with
aa_get_ns(), which is kref_get() on the reference count that the
namespace is released through, without checking whether the namespace
is still in use.  A concurrent removal of a ":"-prefixed namespace
looks the same namespace up and only then takes the parent lock to
remove it, so the last reference can be dropped between the lookup and
the aa_get_ns() call: the reference count then reports the increment on
a zero count and the kernel classifies the following use of the object
as a use-after-free.  A user with CAP_MAC_ADMIN can trigger this by
writing a ":<name>" removal and a ":<name>/<profile>" removal to
/sys/kernel/security/apparmor/.remove concurrently.

refcount_t: addition on 0; use-after-free.
WARNING: lib/refcount.c:25 at refcount_warn_saturate+0xc0/0xe0, CPU#6
Call Trace:
 <TASK>
 aa_lookupn_ns+0xa9/0xc0
 aa_remove_profiles+0x4fb/0x730
 ? __kvmalloc_node_noprof+0x219/0x5c0
 ? __pfx_aa_remove_profiles+0x10/0x10
 ? aa_loaddata_alloc+0x65/0x1f0
 ? _copy_from_user+0x2d/0x80
 ? aa_loaddata_alloc+0x111/0x1f0
 profile_remove+0x2ee/0x4a0
 vfs_write+0x21e/0xcf0
 ? rcu_core+0x29c/0x1740
 ? timerqueue_linked_add+0x1f4/0x3d0
 ? __pfx_vfs_write+0x10/0x10
 ? mutex_lock+0x81/0xe0
 ? __pfx_mutex_lock+0x10/0x10
 ? __pfx_rcu_core+0x10/0x10
 ? __pfx_hrtimer_update_next_event+0x10/0x10
 ? mutex_unlock+0x7b/0xd0
 ? fdget_pos+0x24d/0x4b0
 ksys_write+0xf7/0x1c0
 ? __pfx_ksys_write+0x10/0x10
 ? restore_fpregs_from_fpstate+0x37/0xc0
 do_syscall_64+0xf9/0x540
 entry_SYSCALL_64_after_hwframe+0x77/0x7f
 </TASK>

Fix by rejecting a namespace whose reference count is zero.

Fixes: 3664268f19 ("apparmor: add namespace lookup fns()")
Cc: stable@vger.kernel.org
Signed-off-by: Binbin Deng <18983559317@163.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Wentao Liang
8f1f7f664c apparmor: Fix namespace reference leak in __aa_find_or_create_ns()
When the namespace already exists, the reference taken by aa_get_ns() is
overwritten with ERR_PTR(-EEXIST) without being released. The caller in
apparmorfs.c clears ns on IS_ERR() and so cannot drop it either, leaking
the reference on raced mkdir of an existing namespace.

Release the reference before returning -EEXIST.

Fixes: 73688d1ed0 ("apparmor: refactor prepare_ns() and make usable from different views")
Signed-off-by: Wentao Liang <vulab@iscas.ac.cn>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Guanglei Zhu
afe5d5a747 apparmor: check accept index + 1 is in bounds
aa_lookup_condperms() returns perms[index + 1] when an accept entry has
ACCEPT_FLAG_OWNER set and the subject uid does not match the file uid,
so such an entry consumes two slots in the perms table.  But
verify_dfa_accept_index() only checks that index is within the perms
table, so a policy that sets the owner flag on the last entry is
accepted, and the runtime lookup then reads perms[index + 1] one entry
past the end of the table.

The perms table is allocated by unpack_perms_table() with a u16 size
read from the policy blob, so a crafted policy can place the owner flag
at index size - 1 to reach the out-of-bounds read.

Check that index + 1 is also in bounds when the owner flag is set.

Fixes: 6f442d42c0 ("apparmor: fix profile verification and enable it")
Cc: stable@vger.kernel.org
Signed-off-by: Guanglei Zhu <zhugl3@xiaopeng.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Karl Mehltretter
fcd621debf apparmor: Fix the return value in split_token_from_name() kernel-doc
split_token_from_name() returns ERR_PTR(-EINVAL) for malformed input,
but its kernel-doc describes NULL as the failure result. NULL is instead
a successful result when the name following the token is empty.

Document all three results: the name, NULL for an empty name, and an
error pointer for malformed input.

Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Maxime Bélair
e667fc72f7 apparmor: convert duplicated dfa transitions to match_char()
For historical reasons several matchers duplicate the dfa character
transition instead of using match_char().

This is because aa_dfa_match_until() and aa_dfa_matchn_until() were
written on a branch that did not yet have match_char(), and copied code
from aa_dfa_match(). leftmatch_fb() used the same pattern.

When match_char() added support for diff-encoded states, the change was
never ported to these copies.

match_char() resolves a diff encoded state by using def[state] and
retrying the same character, until it reaches a state with a valid
transition. The copies instead do a simple `state = def[state];` after
the character is consumed, so on a diff encoded state one byte is dropped
and the walk continues from the diff parent in the wrong state.

This makes an unnamed px/Px/cx/Cx transition resolve to no profile, and
exec fails with

  apparmor="DENIED" operation="exec" info="profile transition not found"

Convert the three copies to match_char(). For a dfa with no diff
encoded state this is a no-op.

This bug is latent until the kernel advertises policy/diff-encode.

Closes: https://gitlab.com/apparmor/apparmor/-/work_items/663
Fixes: 21f6066105 ("apparmor: improve overlapping domain attachment resolution")
Fixes: 031dcc8f4e ("apparmor: dfa add support for state differential encoding")
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Maxime Bélair
449195a4bb apparmor: fix table_size() integer overflow on 32 bit
table_size() checks ALIGN(sizeof(struct table_header) + len * el_size, 8)
in size_t, where @len is td_lolen, a u32 user-provided value from the
policy blob. On 32 bit kernels both operations can overflow.

Triggering this bug allows to:
 - overflow a 16 byte allocation with up to 4GiB of policy data
 - store the table header at address ZERO_SIZE_PTR (kvzalloc(0))

However, this bug requires CAP_MAC_ADMIN, only affects 32 bit kernels,
and the copy runs until the machine is destroyed, so it gives no
controllable primitive and is therefore not a security issue.

Compute the size with the checked helpers and return 0 when the result is
not representable, so the callers can reject the table. A valid table is
never 0 bytes, the header alone is 12.

64 bit kernels cannot overflow (these structs are 32 bit), and are hence
not affected.

Fixes: e06f75a6a2 ("AppArmor: dfa match engine")
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:30:53 -07:00
Li RongQing
7ccd884a5e apparmor: avoid potential double free when remapping DFA tables
When unpacking a DFA, aa_dfa_unpack() stores a table in dfa->tables
before attempting to remap a 16-bit table to 32-bit.

However, remap_data16_to_data32() frees the original table when
allocation of the new table fails. This leaves the corresponding
dfa->tables entry pointing to freed memory. If the unpacking then
fails, dfa_free() attempts to free the same table again.

Only publish the table to dfa->tables after any required remapping
has completed successfully, so that dfa->tables never contains a
pointer to a table that has already been freed.

Fixes: 9208c05f9f ("apparmor: add support for 2^24 states to the dfa state machine.")
Cc: stable@vger.kernel.org
Signed-off-by: Li RongQing <lirongqing@baidu.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:29:00 -07:00
Maxime Bélair
07aee062c6 apparmor: report a label allocation failure as -ENOMEM
aa_label_strn_parse() returns -ENOENT for every failure, so a caller
cannot tell "no such profile" from "could not allocate a label".

Report an allocation failure as -ENOMEM.

Fixes: f1bd904175 ("apparmor: add the base fns() for domain labels")
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:28:03 -07:00
Maxime Bélair
f7bd6285ff apparmor: fix a leak on a rejected string table entry
unpack_strs_table() stores each entry into the table only after
validating it, so an entry the validation rejects is never freed. Up
to 64KB leaks per rejected entry.

Store the pointer before validating it.

Fixes: c140dcd124 ("apparmor: make str table more generic and be able to have multiple entries")
Reviewed-by: Ryan Lee <ryan.lee@canonical.com>
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:28:03 -07:00
John Johansen
1f5428b9f9 apparmor: remove unconfined_profile() check in inet socket mediation
When a stacked label is used the early bailout !unconfined(label)
fails, and the individual profile components of the label are checked.
This can lead to aa_profile_af_perm() being called which results in

  WARNING: security/apparmor/net.c:263 at aa_profile_af_perm+0x228/0x3b0

on any inet socket using basic socket mediation.

Remove the AA_BUG(profile_unconfined(profile)) check, it is not needed
as the code already handles the unconfined_profile() case. In addition
also a comment to indicate that this case is covered.

Fixes: 89ac6aa752 ("apparmor: push inet mediation into profile callbacks, and improve auditing")
Reported-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:28:03 -07:00
John Johansen
33ed507162 apparmor: fix refcount leak in aa_get_newest_profile()
The labels_profile() macro is evaluating its argument twice

  #define labels_profile(X) ((X)->vec[(X)->size - 1])

unfortunately aa_get_newest_profile() passes
   aa_get_newest_label(&p->label)
so every call to aa_get_newest_profile results in 2 refcounts
being taken with one being leaked.

There is no need for labels_profile() to be a macro. Convert it to
an inline fn, which ensures all uses are passing the correct struct
and removes the double evaluation.

Fixes: 637f688dc3 ("apparmor: switch from profiles to using labels on contexts")
Cc: stable@vger.kernel.org
Reported-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:28:03 -07:00
Michail Andreas Michalopoulos
4890a8b1a9 apparmor: check address length before reading AF_UNSPEC bind address
bind_map_addr() handles AF_UNSPEC on an IPv4 socket by reading
addr4->sin_addr.s_addr to check for INADDR_ANY. At that point the only
length check done is addrlen >= offsetofend(struct sockaddr, sa_family),
i.e. 2 bytes, while sin_addr sits at offset 4. move_addr_to_kernel()
copies only addrlen bytes into the on-stack sockaddr_storage, so a
bind() with a short AF_UNSPEC address makes AppArmor branch on bytes the
caller never supplied.

Depending on those bytes, a confined task gets -EAFNOSUPPORT instead of
the -EINVAL that inet_bind_sk() returns for the same request. Kernels
built with CONFIG_INIT_STACK_ALL_ZERO read zeroes and happen to behave
correctly.

Check the length first, as inet_bind_sk() does, and as the AF_INET6
case above already does for inet6_bind_sk().

Fixes: 89ac6aa752 ("apparmor: push inet mediation into profile callbacks, and improve auditing")
Assisted-by: LLM
Signed-off-by: Michail Andreas Michalopoulos <mike.michalo@gmail.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:28:03 -07:00
shaos
0497607465 apparmor: mediate AF_UNSPEC socket disconnects
aa_inet_connect_perm() returns success immediately for AF_UNSPEC
before checking the active AppArmor profile.  AF_UNSPEC is the socket
disconnect operation for TCP and UDP.  A process confined by a profile
containing deny network can therefore disconnect inherited sockets
even though ordinary socket creation and connect calls are denied.

console output:
fab5c58d6f/console-output.txt
reproduction kernel config:
b9192c97c9/kernel-config.txt
reproducer:
92c7dd098a/poc.c

Build the kernel from HEAD with the attached reproduction config, then
make a one-file initramfs.  The PoC mounts sysfs and securityfs
itself; DEVTMPFS_MOUNT supplies /dev/console.

    mkdir -p build rootfs
    cp kernel-config.txt build/.config
    make O=build olddefconfig
    make O=build -j"$(nproc)" bzImage
    cc -O2 -static -Wall -Wextra -o poc poc.c
    cp poc rootfs/poc
    (cd rootfs && find poc | cpio -o -H newc --owner=0:0) | gzip -9 > initramfs.cpio.gz
    timeout 900 qemu-system-x86_64 -kernel build/arch/x86/boot/bzImage \
        -initrd initramfs.cpio.gz -append "console=ttyS0 rdinit=/poc panic=-1 loglevel=7 lsm=apparmor security=apparmor apparmor=1" \
        -nographic -m 1024 -smp 1 -no-reboot 2>&1 | tee console.log

Under the deny-network profile, socket() and connect(AF_INET) returned
EACCES, but connect(fd, AF_UNSPEC) returned success and tore down the
inherited connection and listener.  Two fresh boots matched.  A
one-line control that routed AF_UNSPEC through aa_sk_perm returned
EACCES and kept both sockets alive.

Impact and prerequisites: A confined process that inherits a TCP/UDP
socket can bypass the profile's network mediation for disconnect and
disrupt that socket.  The finding does not permit socket creation,
bind, or arbitrary peer connections; no privilege escalation is
demonstrated.

Fixes: 89ac6aa752 ("apparmor: push inet mediation into profile callbacks, and improve auditing")
Signed-off-by: shaos <shawnq1@163.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-29 08:27:30 -07:00
Georgia Garcia
a913281f60 apparmor: don't revalidate inherited files under files->file_lock
aa_inherit_files() revalidates inherited files on exec using
iterate_fd(), which calls the callback with files->file_lock held,
so the revalidation is done with IN_ATOMIC. However the unix socket
mediation path can sleep: aa_unix_file_perm() drops a ref on the
peer's path with path_put(), and unix_fs_perm() -> aa_path_perm()
allocates a buffer with aa_get_buffer(false), resulting in

  BUG: sleeping function called from invalid context at fs/dcache.c:1039
  ...
   dput.part.0+0x24/0x180
   path_put+0x2c/0x60
   aa_unix_file_perm+0x42a/0x17b0
   aa_file_perm+0xcd3/0x1060
   match_file+0x10b/0x190
   iterate_fd+0xe6/0x280
   aa_inherit_files+0x250/0x4f0

Only grab a ref on each file under iterate_fd(), and revalidate it
after the lock is dropped, so revalidation is done with no locks held
and does not need to be atomic. Denied fds are still replaced with
/dev/null, or closed if it can not be opened.

Fixes: b1aea2c196 ("apparmor: fix race in unix socket mediation when peer_path is used")
Cc: stable@vger.kernel.org
Signed-off-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-28 20:16:29 -07:00
Maxime Bélair
4de32fd05c apparmor: fix NULL ctx->peer derefs in unix socket ctx updates
aa_unix_file_perm lazily refreshes the AppArmor context cached on a unix
socket. Two of the helpers it uses assume ctx->peer has already been set:

	update_peer_ctx ->  l = aa_label_merge(old, label, GFP_ATOMIC);
	update_sk_ctx   ->  } else if (aa_label_is_subset(plabel, old)) {

where @old is ctx->peer. Neither aa_label_merge nor aa_label_is_subset
allows NULL. So both fault on the aa_label->size load.

  BUG: kernel NULL pointer dereference, address: 000000000000004c
  RIP: 0010:__aa_label_next_not_in_set+0xb/0xd0
  Call Trace:
   aa_label_is_subset+0x3f/0x70
   aa_unix_file_perm+0x5e8/0x9d0
   aa_file_perm+0x45a/0x550
   apparmor_file_permission+0x44/0xb0
   security_file_permission+0x40/0x100
   rw_verify_area+0x56/0x180
   vfs_write+0x7c/0x480
   ksys_write+0xbf/0xf0

ctx->peer is only recorded for stream connections and socket pairs.
unix_dgram_connect sets unix_peer(sk) without going through that path,
so a connected AF_UNIX datagram socket has unix_peer(sk) set while
ctx->peer is still NULL, and the first write that needs revalidation
reaches the helpers above.

Both derefs date back to the Fixes: commit, but the update_sk_ctx() one
was dormant until commit 4483efe4f2 ("apparmor: fix shadowing of plabel
that prevents cache from being updated") stopped @plabel being shadowed,
which is why bisecting the oops lands there.

A NULL @old just means no peer label has been recorded yet, so install
the label directly instead of merging or comparing against it.

Fixes: 88fec3526e ("apparmor: make sure unix socket labeling is correctly updated.")
Cc: stable@vger.kernel.org
Reported-by: Aurelien Jarno <aurelien@aurel32.net>
Closes: https://bugs.debian.org/1145111
Tested-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
Reviewed-by: Georgia Garcia <georgia.garcia@canonical.com>
Signed-off-by: Maxime Bélair <maxime.belair@canonical.com>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-10-28 20:15:45 -07:00
Linus Torvalds
8a36f53fd5 mm.git review status for linus..mm-stable
Everything:
 
 Total patches:       213
 Fixes: tags:         69
 cc:stable patches:   43
 Reviews/patch:       2.04
 Reviewed rate:       86%
 
 Excluding DAMON:
 
 Total patches:       192
 Fixes: tags:         63
 cc:stable patches:   39
 Reviews/patch:       2.18
 Reviewed rate:       89%
 
 Excluding DAMON and selftests:
 
 Total patches:       182
 Fixes: tags:         57
 cc:stable patches:   39
 Reviews/patch:       2.23
 Reviewed rate:       89%
 
 Summary of series in this merge:
 
 - "mm: make VMA flag semantics explicit, eliminate VM_SPECIAL"
   (Lorenzo Stoakes (ARM)):
 
   Replace VM_SPECIAL with helpers describing mapping ownership and
   behavior.  Enforce the mmap flag rules and convert affected drivers,
   removing ambiguous tests shared by driver mappings and ordinary memory.
 
 - "support kselftest on nommu platform" (Hajime Tazaki):
 
   Add opt-in mmap and mremap tests for NOMMU systems.  Teach the runner to
   avoid its fork-dependent timeout command and document the build and
   runtime requirements.
 
 - "mm/collapse: separate a collapse from its callers"
   (Kiryl Shutsemau (Meta)):
 
   Separate huge-page collapse from caller policy.  Replace khugepaged
   identity checks with explicit permissions, and separate scanning from
   collapse with the mmap_lock drop in one place.
 
 - "mm: implement and use vma_has_anon_rmap(), silence KCSAN"
   (Lorenzo Stoakes (ARM)):
 
   Provide a common helper for testing whether a VMA has anonymous reverse
   mappings.  Document the locking rules, annotate intentional concurrent
   reads for KCSAN, and convert the core MM callers.
 
 - "mm/sparse: remove SECTION_MARKED_PRESENT and further cleanups"
   (David Hildenbrand (Arm)):
 
   Remove SECTION_MARKED_PRESENT in favor of the early-section flag.
   Simplify sparse memory initialization, section metadata handling and
   related PFN validity checks.
 
 - "sh: remove NUMA and SPARSEMEM support" (Mike Rapoport (Microsoft)):
 
   Remove SuperH NUMA and SPARSEMEM support.  The extra memory banks have
   been unusable since the NO_BOOTMEM conversion, leaving only the code and
   data overhead.
 
 - "mm: Unify device DAX and HugeTLB vmemmap population paths"
   (Muchun Song):
 
   Unify the generic device DAX and HugeTLB vmemmap population paths and
   shared tail-page handling.  Remove the duplicate DAX machinery while
   retaining the powerpc radix implementation.
 
 - "kselftest: mm: fix some failure of split_huge_page_test" (Yeoreum Yun):
 
   Fix huge-page split tests racing with khugepaged recollapse.  Use pagemap
   and page flags instead of VMA-boundary assumptions which fail when glibc
   has already enabled THP.
 
 - "memcg: move memcgid refcount to objcg to unpin dying memcgs"
   (Bingfang Guo):
 
   Let dying memcgs be freed while swapped-out shmem still holds their IDs.
   Move ID references to reparentable objcgs, with the necessary swap
   accounting and RCU lifetime changes.
 
 - "mm/truncate: fix data loss when truncating straddling large folios"
   (Zhang Yi):
 
   Preserve out-of-range data when truncating straddling large folios.  Fix
   a lookup race and split-failure handling, and handle minimum folio orders
   for the forthcoming ext4 iomap buffered I/O path.
 
 - "mm/damon: introduce damos quota goal target metric complement flag"
   (SJ Park):
 
   Let DAMOS quota goals use a metric's complement, so utilization can also
   express free-memory goals without adding separate metrics.  Add the sysfs
   interface, documentation and tests.
 
 - "arm64/mm: Standardize printing for pgtable entries" (Anshuman Khandual):
 
   Use the generic formatter for arm64 page-table entries, ready for future
   wider entries.  Move the safe-PTE-update check out of the header to avoid
   an include cycle.
 
 - "mm: kmsan: fix iounmap metadata teardown" (Dima Koziuk):
 
   Fix KMSAN metadata leaks on iounmap and failed ioremap allocations.  Free
   backing pages before removing their mappings, and share the teardown with
   partial-allocation cleanup.
 
 - "mm/damon/core: preserve quota state when constructing schemes"
   (Karl Mehltretter):
 
   Preserve running DAMOS quota state while validating parameter updates.
   Even rejected updates could reset accounting and exceed the quota window;
   add tests for both accepted and rejected updates.
 
 - "mm/vmalloc: fix vmalloc_dump_obj VA lookup" (Ye Liu):
 
   Fix vmalloc_dump_obj() lookups for last-page addresses and allocations
   spanning vmap zones.  These allocations were being missed in diagnostic
   output.
 
 - "mm: various (urgent?) fixes" (David Hildenbrand (Arm)):
 
   Fix mmap charge leaks and hugetlb use-after-free, wrong-address
   unmapping, stuck locks and endless faults.  Also preserve reservations on
   failed mremap and handle stale userfaultfd bits.
 
 - "maple_tree: fix maple_range_64 crashes in RCU mode" (Dimitris Charisis):
 
   Fix pointer and metadata confusion during RCU destruction of
   maple_range_64 nodes, avoiding double frees and invalid accesses.  Add a
   regression test; no in-tree user currently uses this combination.
 
 - "mm: fix hugetlb NR_HUGETLB accounting on folio migration" (Hongfu Li):
 
   Fix hugetlb migration and preallocation accounting so /proc/vmstat
   retains the correct count and memory.numa_stat follows the folio to its
   new node.
 
 - "mm/damon: fix a minor bug, clean code, and add a test" (SJ Park):
 
   Fix 32-bit DAMON age overflow which made old regions look young.  Share
   hugetlb folio acquisition code and add a regression test for the
   previously fixed last-region skipping bug.
 
 - "mm/damon/core: cleanup code, reduce stack usage, and add kunit"
   (SJ Park):
 
   Reduce kdamond stack usage and remove unused enums.  Add deterministic
   PSI quota-goal tests which do not depend on the machine's current memory
   pressure.
 
 - "mm/damon: fix the temporal goal tuner's size quota conversion"
   (Donggeun Yoo):
 
   Bound the temporal tuner's quota conversion to prevent overflow and zero
   effective quotas, which could stop schemes making progress.  Add boundary
   tests.
 
 - "Don't use GFP_DMA when calling dma_alloc_coherent" (Baoquan He):
 
   Remove redundant GFP_DMA flags from coherent DMA allocation calls.  The
   DMA API already selects the zone from device limits and ignores the
   caller's flag.
 
 - "kselftest: mm: fix intermittent failure khugepaged test" (Yeoreum Yun):
 
   Propagate child-process failures in the khugepaged tests and prevent
   background collapse from racing their checks.  This removes false passes
   and intermittent failures.
 
 - "MAINTAINERS: cover all hugetlb headers under HUGETLB SUBSYSTEM"
   (Enze Li):
 
   Cover all hugetlb headers in MAINTAINERS so get_maintainer.pl finds the
   right maintainers.  Also label the closing hugetlb_cgroup.h include
   guard.
 
 Summary of the 65 singletons in this merge:
 
 The singletons include a few worthwhile performance fixes. Avoiding
 unnecessary reverse-map tree updates gave a reported 15.9% improvement
 in UnixBench's execl test on a 192-core x86 system. A reclaim retry fix
 stops defrag_mode from spinning under memory.low protection; a reported
 file-creation stress test ran 5.7 times faster, with far less memory
 pressure. Narrower hugetlb invalidations also spare KVM guests needless
 refaults: the reported Redis-in-VM P99 QPS penalty while punching holes
 fell from 7.09% to 1.45%.
 
 Several fixes prevent lost data or corrupted memory. Lazyfree huge-page
 races with mremap()/munmap() could lose data or access freed memory, and
 MADV_COLD could lose a concurrent write's dirty bit. Another fix
 prevents stale migration entries from outliving large folios. On
 filesystems with blocks smaller than a page, extending a file by 4 GiB
 or more could expose bytes written past the old EOF through mmap instead
 of zeroes. That is fixed, along with use-after-free races in
 PAGEMAP_SCAN during process exit and in memory-cgroup accounting on
 PREEMPT_RT kernels.
 
 Other fixes stop UFFDIO_MOVE spinning forever on pinned large folios,
 which could wedge other memory operations, and stop mremap() leaking
 commit charges until allocations fail under strict overcommit. A further
 fix keeps userfaultfd tracking intact on neighboring mappings. NUMA
 binding no longer prevents long-term pins when the chosen node has only
 movable memory, fixing QEMU/VFIO startup and io_uring buffer
 registration failures. MGLRU also gets a fix for early-boot crashes with
 memory cgroups disabled at boot, notably in small crash kernels.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQTTMBEPP41GrTpTJgfdBJ7gKXxAjgUCat66sAAKCRDdBJ7gKXxA
 jrQrAP99kgSXRdlmRZbHeRBHQ6KvI4XnLvQ78MDIzZ3zmBaOugEA5jiIsK2/snFD
 3VaV0oipVZpuwJkVJE6zFkh0tcHgTAo=
 =DHrN
 -----END PGP SIGNATURE-----

Merge tag 'mm-stable-2026-10-25-19-27' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm

Pull more MM updates from Andrew Morton:

 - "mm: make VMA flag semantics explicit, eliminate VM_SPECIAL" (Lorenzo
   Stoakes):

   Replace VM_SPECIAL with helpers describing mapping ownership and
   behavior. Enforce the mmap flag rules and convert affected drivers,
   removing ambiguous tests shared by driver mappings and ordinary
   memory.

 - "support kselftest on nommu platform" (Hajime Tazaki):

   Add opt-in mmap and mremap tests for NOMMU systems. Teach the runner
   to avoid its fork-dependent timeout command and document the build
   and runtime requirements.

 - "mm/collapse: separate a collapse from its callers" (Kiryl
   Shutsemau):

   Separate huge-page collapse from caller policy. Replace khugepaged
   identity checks with explicit permissions, and separate scanning from
   collapse with the mmap_lock drop in one place.

 - "mm: implement and use vma_has_anon_rmap(), silence KCSAN" (Lorenzo
   Stoakes):

   Provide a common helper for testing whether a VMA has anonymous
   reverse mappings. Document the locking rules, annotate intentional
   concurrent reads for KCSAN, and convert the core MM callers.

 - "mm/sparse: remove SECTION_MARKED_PRESENT and further cleanups"
   (David Hildenbrand):

   Remove SECTION_MARKED_PRESENT in favor of the early-section flag.
   Simplify sparse memory initialization, section metadata handling and
   related PFN validity checks.

 - "sh: remove NUMA and SPARSEMEM support" (Mike Rapoport):

   Remove SuperH NUMA and SPARSEMEM support. The extra memory banks have
   been unusable since the NO_BOOTMEM conversion, leaving only the code
   and data overhead.

 - "mm: Unify device DAX and HugeTLB vmemmap population paths" (Muchun
   Song):

   Unify the generic device DAX and HugeTLB vmemmap population paths and
   shared tail-page handling. Remove the duplicate DAX machinery while
   retaining the powerpc radix implementation.

 - "kselftest: mm: fix some failure of split_huge_page_test" (Yeoreum
   Yun):

   Fix huge-page split tests racing with khugepaged recollapse. Use
   pagemap and page flags instead of VMA-boundary assumptions which fail
   when glibc has already enabled THP.

 - "memcg: move memcgid refcount to objcg to unpin dying memcgs"
   (Bingfang Guo):

   Let dying memcgs be freed while swapped-out shmem still holds their
   IDs. Move ID references to reparentable objcgs, with the necessary
   swap accounting and RCU lifetime changes.

 - "mm/truncate: fix data loss when truncating straddling large folios"
   (Zhang Yi):

   Preserve out-of-range data when truncating straddling large folios.
   Fix a lookup race and split-failure handling, and handle minimum
   folio orders for the forthcoming ext4 iomap buffered I/O path.

 - "mm/damon: introduce damos quota goal target metric complement flag"
   (SJ Park):

   Let DAMOS quota goals use a metric's complement, so utilization can
   also express free-memory goals without adding separate metrics. Add
   the sysfs interface, documentation and tests.

 - "arm64/mm: Standardize printing for pgtable entries" (Anshuman
   Khandual):

   Use the generic formatter for arm64 page-table entries, ready for
   future wider entries. Move the safe-PTE-update check out of the
   header to avoid an include cycle.

 - "mm: kmsan: fix iounmap metadata teardown" (Dima Koziuk):

   Fix KMSAN metadata leaks on iounmap and failed ioremap allocations.
   Free backing pages before removing their mappings, and share the
   teardown with partial-allocation cleanup.

 - "mm/damon/core: preserve quota state when constructing schemes" (Karl
   Mehltretter):

   Preserve running DAMOS quota state while validating parameter
   updates. Even rejected updates could reset accounting and exceed the
   quota window; add tests for both accepted and rejected updates.

 - "mm/vmalloc: fix vmalloc_dump_obj VA lookup" (Ye Liu):

   Fix vmalloc_dump_obj() lookups for last-page addresses and
   allocations spanning vmap zones. These allocations were being missed
   in diagnostic output.

 - "mm: various (urgent?) fixes" (David Hildenbrand):

   Fix mmap charge leaks and hugetlb use-after-free, wrong-address
   unmapping, stuck locks and endless faults. Also preserve reservations
   on failed mremap and handle stale userfaultfd bits.

 - "maple_tree: fix maple_range_64 crashes in RCU mode" (Dimitris
   Charisis):

   Fix pointer and metadata confusion during RCU destruction of
   maple_range_64 nodes, avoiding double frees and invalid accesses. Add
   a regression test; no in-tree user currently uses this combination.

 - "mm: fix hugetlb NR_HUGETLB accounting on folio migration" (Hongfu
   Li):

   Fix hugetlb migration and preallocation accounting so /proc/vmstat
   retains the correct count and memory.numa_stat follows the folio to
   its new node.

 - "mm/damon: fix a minor bug, clean code, and add a test" (SJ Park):

   Fix 32-bit DAMON age overflow which made old regions look young.
   Share hugetlb folio acquisition code and add a regression test for
   the previously fixed last-region skipping bug.

 - "mm/damon/core: cleanup code, reduce stack usage, and add kunit" (SJ
   Park):

   Reduce kdamond stack usage and remove unused enums. Add deterministic
   PSI quota-goal tests which do not depend on the machine's current
   memory pressure.

 - "mm/damon: fix the temporal goal tuner's size quota conversion"
   (Donggeun Yoo):

   Bound the temporal tuner's quota conversion to prevent overflow and
   zero effective quotas, which could stop schemes making progress. Add
   boundary tests.

 - "Don't use GFP_DMA when calling dma_alloc_coherent" (Baoquan He):

   Remove redundant GFP_DMA flags from coherent DMA allocation calls.
   The DMA API already selects the zone from device limits and ignores
   the caller's flag.

 - "kselftest: mm: fix intermittent failure khugepaged test" (Yeoreum
   Yun):

   Propagate child-process failures in the khugepaged tests and prevent
   background collapse from racing their checks. This removes false
   passes and intermittent failures.

 - "MAINTAINERS: cover all hugetlb headers under HUGETLB SUBSYSTEM"
   (Enze Li):

   Cover all hugetlb headers in MAINTAINERS so get_maintainer.pl finds
   the right maintainers. Also label the closing hugetlb_cgroup.h
   include guard.

Summary of the 65 singletons in this merge:

  The singletons include a few worthwhile performance fixes. Avoiding
  unnecessary reverse-map tree updates gave a reported 15.9% improvement
  in UnixBench's execl test on a 192-core x86 system. A reclaim retry
  fix stops defrag_mode from spinning under memory.low protection; a
  reported file-creation stress test ran 5.7 times faster, with far less
  memory pressure. Narrower hugetlb invalidations also spare KVM guests
  needless refaults: the reported Redis-in-VM P99 QPS penalty while
  punching holes fell from 7.09% to 1.45%.

  Several fixes prevent lost data or corrupted memory. Lazyfree
  huge-page races with mremap()/munmap() could lose data or access freed
  memory, and MADV_COLD could lose a concurrent write's dirty bit.
  Another fix prevents stale migration entries from outliving large
  folios. On filesystems with blocks smaller than a page, extending a
  file by 4 GiB or more could expose bytes written past the old EOF
  through mmap instead of zeroes. That is fixed, along with
  use-after-free races in PAGEMAP_SCAN during process exit and in
  memory-cgroup accounting on PREEMPT_RT kernels.

  Other fixes stop UFFDIO_MOVE spinning forever on pinned large folios,
  which could wedge other memory operations, and stop mremap() leaking
  commit charges until allocations fail under strict overcommit. A
  further fix keeps userfaultfd tracking intact on neighboring mappings.
  NUMA binding no longer prevents long-term pins when the chosen node
  has only movable memory, fixing QEMU/VFIO startup and io_uring buffer
  registration failures. MGLRU also gets a fix for early-boot crashes
  with memory cgroups disabled at boot, notably in small crash kernels.

* tag 'mm-stable-2026-10-25-19-27' of git://git.kernel.org/pub/scm/linux/kernel/git/akpm/mm: (213 commits)
  mm: multi-gen LRU: fix NULL lruvec->pgdat deref with memcg disabled on cmdline
  mm/page_counter: use WRITE_ONCE() for emin/elow when parent is the root
  mm/memcontrol: publish null pointer before dropping css reference
  test_maple_tree: test maple_range_64 node in RCU mode
  maple_tree: fix maple_range_64 crashes in RCU mode
  mm/vma: avoid broken uffd merge on mremap
  tools/testing/shared: catch a failed posix_memalign()
  mm/damon/core: remove unreachable damos charge_{target,addr}_from
  mm/shrinker: allocate shrinker_info_unit from a dedicated kmem_cache
  riscv: mm: exclude invalid THP PMDs from page table check
  mm/damon/core: filter out damos address filter-split failed region
  fs/proc/task_mmu: pin mm_users in do_pagemap_scan()
  mm/mempolicy: apply bind policies against the scoped allocation zone
  mm/vmscan: reclaim every zone in per-node proactive reclaim
  mm/mremap: correctly uncharge accountable VMAs in error path
  mm/mremap: populate calculated fields in vrm state correctly
  MAINTAINERS: add an entry for MEMORY MANAGEMENT - MEMORY MAP
  mm: bdi: reset min_ratio after the sysfs attributes are gone
  mm/page_vma_mapped: continue past nonmatching huge PMDs
  selftests/mm: skip hugetlb cgroup v2 tests without the needed controllers
  ...
2026-10-27 12:23:17 -10:00
Linus Torvalds
62c4575285 vfs-7.4-rc1.keyring
Please consider pulling these changes from the signed vfs-7.4-rc1.keyring tag.
 
 Thanks!
 Christian
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRAhzRXHqcMeLMyaSiRxhvAZXjcogUCatyIKQAKCRCRxhvAZXjc
 ogjWAQD1no3bS2OTeI91M1KGxwm4XoqBwg5DaRtW9SG1I284CgEA/lRwCMBT6Op7
 on+ebYhp9krrycMx5n1xGDhL0lm+zg4=
 =5miC
 -----END PGP SIGNATURE-----

Merge tag 'vfs-7.4-rc1.keyring' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs

Pull vfs keyring updates from Christian Brauner:
 "The kernel has two keyrings that userspace fills with X.509
  certificates at boot: .fs-verity for fs-verity built-in signatures
  and .dm-verity for dm-verity root hash signatures.

  Neither is linked into any process keyring. Hence, request_key() and
  KEYCTL_SEARCH can't find them. The only way for userspace to identify
  them is to read their serial number out of /proc/keys. That is not
  just a large file often the names can also be reused and appear
  multiple times which allows forging these keyrings.

  This adds two fixed special key ids, KEY_SPEC_DM_VERITY_KEYRING and
  KEY_SPEC_FS_VERITY_KEYRING next to KEY_SPEC_BPF_KEYRING. The latter
  went in through bpf-next this merge window.

  lookup_user_key() resolves the fixed key ids to the two keyrings. So
  userspace can add a dm-verity (fixed keyring id: -10) certificate with

	keyctl padd asymmetric "" -10 < cert.der

  and seal the keyring with

	keyctl restrict_keyring -10

  without looking anything up first"

* tag 'vfs-7.4-rc1.keyring' of git://git.kernel.org/pub/scm/linux/kernel/git/vfs/vfs:
  Documentation: keys: document IDs added since KEY_SPEC_REQKEY_AUTH_KEY
  keys: add KEY_SPEC_FS_VERITY_KEYRING
  keys: add KEY_SPEC_DM_VERITY_KEYRING
2026-10-27 08:01:30 -10:00
Lorenzo Stoakes (ARM)
c6ce4378f2 selinux: reject writable opens of policy file, drop mmap shared/write check
The policy file has no write method and is exposed read-only (S_IRUGO in
selinux_files[]), yet sel_open_policy() performs no open mode check, so a
CAP_DAC_OVERRIDE caller can open it O_RDWR. Reject FMODE_WRITE at open, as
kernfs does.

The file can then never be mapped with FMODE_WRITE, so do_mmap() always
clears VM_MAYWRITE and VM_SHARED for MAP_SHARED mappings and the VM_SHARED
check in sel_mmap_policy() cannot be reached. Remove it.

This also stops sel_mmap_policy() clearing VM_MAYWRITE on a mapping that is
neither a PFN map nor a mixed map, ahead of the core enforcing that only
such mappings may do so.

Link: https://lore.kernel.org/20261013-b4-mmap-prepare-vma-flag-sanify-v6-12-1aa3c9b139f9@kernel.org
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Reviewed-by: Jann Horn <jannh@google.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Reviewed-by: Suren Baghdasaryan <surenb@google.com>
Acked-by: David Hildenbrand (Arm) <david@kernel.org>
Cc: Liam R. Howlett <liam@infradead.org>
Cc: Vlastimil Babka <vbabka@kernel.org>
Cc: Pedro Falcato <pfalcato@suse.de>
Cc: Mike Rapoport <rppt@kernel.org>
Cc: Michal Hocko <mhocko@suse.com>
Cc: Jonathan Corbet <corbet@lwn.net>
Cc: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: Dennis Dalessandro <dennis.dalessandro@cornelisnetworks.com>
Cc: Jason Gunthorpe <jgg@ziepe.ca>
Cc: Leon Romanovsky <leon@kernel.org>
Cc: Jaroslav Kysela <perex@perex.cz>
Cc: Takashi Iwai <tiwai@suse.com>
Cc: Alexei Starovoitov <ast@kernel.org>
Cc: Daniel Borkmann <daniel@iogearbox.net>
Cc: Andrii Nakryiko <andrii@kernel.org>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Cc: Zi Yan <ziy@nvidia.com>
Cc: Baolin Wang <baolin.wang@linux.alibaba.com>
Cc: Nico Pache <nico.pache@linux.dev>
Cc: Ryan Roberts <ryan.roberts@arm.com>
Cc: Dev Jain <dev.jain@arm.com>
Cc: Barry Song <baohua@kernel.org>
Cc: Lance Yang <lance.yang@linux.dev>
Cc: Usama Arif <usama.arif@linux.dev>
Cc: Kiryl Shutsemau <kas@kernel.org>
Cc: Doug Gilbert <dgilbert@interlog.com>
Cc: James Bottomley <james.bottomley@hansenpartnership.com>
Cc: Martin K. Petersen <mkp@kernel.org>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Helge Deller <deller@gmx.de>
Cc: Sebastian Reichel <sre@kernel.org>
Cc: John Hubbard <jhubbard@nvidia.com>
Cc: Peter Xu <peterx@redhat.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Cc: Oleg Nesterov <oleg@redhat.com>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Borislav Petkov <bp@alien8.de>
Cc: Dave Hansen <dave.hansen@linux.intel.com>
Cc: Arnaldo Carvalho de Melo <acme@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Rik van Riel <riel@surriel.com>
Cc: Harry Yoo <harry@kernel.org>
Cc: Juri Lelli <juri.lelli@redhat.com>
Cc: Vincent Guittot <vincent.guittot@linaro.org>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Will Deacon <will@kernel.org>
Cc: Aneesh Kumar K.V <aneesh.kumar@kernel.org>
Cc: Nicholas Piggin <npiggin@gmail.com>
Cc: Arnd Bergmann <arnd@arndb.de>
Cc: Muchun Song <muchun.song@linux.dev>
Cc: Oscar Salvador <osalvador@suse.de>
Cc: Matthew Wilcox (Oracle) <willy@infradead.org>
Cc: Jan Kara <jack@suse.cz>
Cc: Marc Zyngier <maz@kernel.org>
Cc: Oliver Upton <oupton@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Anup Patel <anup@brainfault.org>
Cc: Paul Walmsley <pjw@kernel.org>
Cc: Palmer Dabbelt <palmer@dabbelt.com>
Cc: Albert Ou <aou@eecs.berkeley.edu>
Cc: Christian Borntraeger <borntraeger@linux.ibm.com>
Cc: Janosch Frank <frankja@linux.ibm.com>
Cc: Claudio Imbrenda <imbrenda@linux.ibm.com>
Cc: Alexander Gordeev <agordeev@linux.ibm.com>
Cc: Gerald Schaefer <gerald.schaefer@linux.ibm.com>
Cc: Heiko Carstens <hca@linux.ibm.com>
Cc: Vasily Gorbik <gor@linux.ibm.com>
Cc: David S. Miller <davem@davemloft.net>
Cc: Andreas Larsson <andreas@gaisler.com>
Cc: Al Viro <viro@zeniv.linux.org.uk>
Cc: Christian Brauner <brauner@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Joshua Hahn <joshua.hahnjy@gmail.com>
Cc: Rakie Kim <rakie.kim@sk.com>
Cc: Byungchul Park <byungchul@sk.com>
Cc: Gregory Price <gourry@gourry.net>
Cc: Ying Huang <ying.huang@linux.alibaba.com>
Cc: Alistair Popple <apopple@nvidia.com>
Cc: Chris Li <chrisl@kernel.org>
Cc: Kairui Song <kasong@tencent.com>
Cc: Kemeng Shi <shikemeng@huaweicloud.com>
Cc: Nhat Pham <nphamcs@gmail.com>
Cc: Baoquan He <baoquan.he@linux.dev>
Cc: Youngjun Park <youngjun.park@lge.com>
Cc: Johannes Weiner <hannes@cmpxchg.org>
Cc: Qi Zheng <qi.zheng@linux.dev>
Cc: Shakeel Butt <shakeel.butt@linux.dev>
Cc: Axel Rasmussen <axelrasmussen@google.com>
Cc: Yuanchu Xie <yuanchu@google.com>
Cc: Wei Xu <weixugc@google.com>
Cc: Chengming Zhou <chengming.zhou@linux.dev>
Cc: Michal Hocko <mhocko@kernel.org>
Cc: Miklos Szeredi <miklos@szeredi.hu>
Cc: Xu Xin <xu.xin@linux.dev>
Cc: Ihor Solodrai <ihor.solodrai@linux.dev>
Cc: Bert Karwatzki <spasswolf@web.de>
2026-10-24 01:56:13 -07:00
Linus Torvalds
55fbedcec6 bpf-next-7.4
-----BEGIN PGP SIGNATURE-----
 
 iQJRBAABCgA7FiEE+soXsSLHKoYyzcli6rmadz2vbToFAmrY/GYdHGFsZXhlaS5z
 dGFyb3ZvaXRvdkBnbWFpbC5jb20ACgkQ6rmadz2vbTrF3w//W1IXtb7BHM5DqyRY
 +IUpLlVdJETLJpdxHGq4SMGU7T+JpBJ7e58HIa9bNfyFaeOFuIvH4dy284RHhr8T
 3wPR61KmX4hZlmqz17lSKM4E4cnaYW/NMYfp4acA/VRNcvcM+IiGnuhzcFyIMs3w
 mPlw/r3rW7Cn7E2Ri2hRV/ZQoT7FyI7LtUEtHU8TUE9kh+T2LTut+FWMJrHe5w0J
 LDFwhVqZE0dWZ4695PK6cEIh8uxRJBnmIyMtN+zLBOtqAjiOSNNhFssdSCIkjPEe
 X9Xz1Zvqa8Z5QsyRsrwK4S62pnh0pVshQ8fDjrXKY7fkMPpzTvOfqOGS3qhOlw2y
 sz853Repug0ZerePFnPnfTIhRIcXagTT11BJUDhUzgy9/Cra3s0vY6c9/MrxTamh
 3Xpu/UNl8AIqC/OnbAo8kJ9aKAG6olIBHYIsVOUYk3tH8m2HaVqpKXKRKfqshSDT
 YyKoGQE8g9gemS44/RSHKi6QI2jUxNwcOI8FBzViDZaeE476Zvv/fHNC5Tv7lwmm
 5qGbcem9sakcd+n17aLy0xKYE2kUSQQLi/J80AY7gMR9VlGsbYPZ8KX8HeSaSLRy
 7SMn2dBvNmFaFNgWdLQn4dmBFhvuVgZP6A/ZTreCLuXjBcPo1TnYkVwi3eye4eY/
 CwgWBoUJTIqMMt+bRyNgBK0+5rQ=
 =kneb
 -----END PGP SIGNATURE-----

Merge tag 'bpf-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next

Pull bpf updates from Alexei Starovoitov:
 "Major changes:

   - Introduce scalar evolution (SCEV) analysis in the verifier.

     It infers how registers and stack slots change in a loop and lets
     the verifier check bounded loops with induction variables as ranges
     instead of walking every iteration. The number of processed insns
     drops ten fold in programs with loops (Eduard Zingerman)

   - Add 'callx' instruction: indirect call of a static BPF subprogram.

     The address is taken with ld_imm64 or loaded from read-only data.
     Supported by x86-64, arm64 and riscv64 JITs (Alexei Starovoitov, Pu
     Lehui)

   - Add unwind_goto and unwind_exit instructions, so that Rust panic or
     C++ exception can run destructors of every frame it passes through.
     The normal path is free of unwind code. Supported by x86-64 and
     arm64 JITs (Alexei Starovoitov)

   - Support programs compiled by rust-bpf: treat load and store through
     a number as arena access with BPF_F_ARENA_SCALAR, accept rust names
     in BTF (Alexei Starovoitov)

   - Raise BPF program stack size from 512 bytes to 2 KiB on x86-64 and
     arm64 (Kumar Kartikeya Dwivedi)

   - Support struct, union and __int128 up to 16 bytes passed and
     returned by value in BPF subprograms and kfuncs, and fix x86-64 and
     arm64 trampolines for such arguments (Yonghong Song)

   - Introduce a common way to attach struct_ops to a cgroup via
     bpf_link. bpf_tcp_ops is the first user and mirrors TCP sock_ops
     callbacks (Martin KaFai Lau, Amery Hung)

   - Describe inlined functions in BTF. New kinds tell where the inline
     sites are and how to fetch the arguments there.

     CONFIG_DEBUG_INFO_BTF_INLINE keeps it apart from the main BTF in
     .BTF.inline section or in btf_vmlinux_inline.ko (Alan Maguire)

   - Fix many memory safety, lifetime and locking bugs in BPF core,
     verifier, iterators, local storage, dynptr, devmap, cpumap and
     seg6local (Josef Bacik, Alexei Starovoitov)

   - Diff stat is dominated by selftests and by removal of
     lib/test_bpf.c. Its 16k lines of instruction tests were converted
     to BPF selftests that BPF CI runs on every architecture it covers
     (Daniel Borkmann)

  Other features and fixes:

   - Add KASAN checks to memory accesses of JITed programs on x86-64
     (Alexis Lothoré)

   - Complete unification of helper, kfunc and subprog argument checks
     in the verifier (Amery Hung)

   - Add bpf_copy_from_user_mm[_str]() kfuncs (Anastasios Papagiannis)

   - Various features and fixes (Daniel Borkmann):
       - Add .bpf keyring for program signature verification, modelled
         after dm-verity keyring, and support ML-DSA in signing tools
       - Emit shorter and faster code in x86-64 JIT for patterns that
         LLVM generates
       - Fix various issues in gotox handling

   - Let BPF LSM set xattrs at inode creation with bpf_inode_init_xattr()
     (David Windsor, Daniel Borkmann)

   - Use sleepable page allocation in sleepable arena paths. Fix races
     between arena free, allocation and user page fault (Emil Tsalapatis)

   - Switch BPF crypto from lskcipher to AES-CBC and AES-ECB libraries
     (Eric Biggers)

   - Add bpf_proactive_reclaim() kfunc (Hui Zhu)

   - Render decl_tags in libbpf btf_dump and add tests for bpftool C
     dump (Ihor Solodrai)

   - Speed up tracing_multi attach on x86 (Jiri Olsa)

   - Various features and fixes (Kumar Kartikeya Dwivedi):
       - Add BPF_PROG_STREAM_OPEN command to read BPF streams through a
         file descriptor with poll support
       - Let kernel structs publish arena pointers with __arena type tag
       - Fix __uninit kfunc output buffers and fastcall rewrite with
         indirect stack accesses
       - Refuse CO-RE relocations for signed programs

   - Add enqueue_rcvq and dequeue_rcvq hooks to bpf_tcp_ops to adjust
     sk_rcvlowat and avoid unnecessary wakeups (Kuniyuki Iwashima)

   - Add bpf_ksock_sendto() kfunc and allow ksock connect and send from
     bpf_wq (Mahe Tardy)

   - Fix racy plt target update in arm64 bpf_arch_text_poke()
     (Matthew Wood)

   - Restructure BPF selftests Makefile as a layered build
     (Mykola Lysenko)

   - Speed up hash map lookups for u32 and u64 keys (Mykyta Yatsenko)

   - Add signed div/mod, movsx, bswap and gotol to MIPS JITs, signed
     div/mod to parisc JITs (Nicholas Dudar, Johan Almbladh)

   - Fix stack overflow in build ID parser on 32-bit (Nickolai
     Zeldovich)

   - Add stack arguments, signed arena loads and gotox to riscv64 JIT.
     Pu Lehui is now co-maintainer of riscv BPF JITs (Pu Lehui, Chen
     Pei, Feng Jiang)

   - Add bpf_call_rcu() and bpf_call_rcu_tasks_trace() kfuncs. Support
     fetching and/or/xor atomics in arena on x86-64 (Puranjay Mohan)

   - Fix flaky selftests, selftests with clang 23 and bpf-gcc
     (Qiliang Yuan, KaFai Wan, Vineet Gupta)

   - Fix builds broken by fatal resolve_btfids warnings, BTF generation
     on ARC, and define arch_cmpxchg_local() on arc, hexagon and
     openrisc (Sasha Levin)

   - Reduce memory use of hash maps by up to 50% per element
     (T.J. Mercier)

   - Mark pointer fields of sched_ext ops arguments as trusted (Tejun
     Heo)

   - Remove legacy bpf_asm, bpf_dbg and bpf_jit_disasm tools (Xia Yan)

   - Fix index overflow in queue and stack maps, arena range tree after
     allocation failure, tail call loop after freplace detach, lost
     signal in bpf_send_signal() (Yuan Chen)

   - Many more fixes and cleanups"

* tag 'bpf-next-7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next: (660 commits)
  selftests/bpf: Time tc_edt from its first packet with data
  selftests/bpf: Test unwind_exit of an exception callback
  selftests/bpf: Tests for 32-bit scalar evolution bounds computation
  bpf: Reject unwind_goto and unwind_exit in offloaded progs
  bpf: Support 32-bit linear scalar evolution
  bpf: Make unwind_exit of an exception callback exit in JITs
  selftests/bpf: Test forbidden bpf_ksock_sendto() LSM attach
  selftests/bpf: Test ksock sendto()
  bpf: Add bpf_ksock_sendto() kfunc
  selftests/bpf: Test unwinding from R0: R2 subprog
  selftests/bpf: Add a C++ prog with exceptions
  selftests/bpf: Add tests for unwind_goto and unwind_exit
  bpf, arm64: Support unwind_goto and unwind_exit
  bpf, x86: Support unwind_goto and unwind_exit
  bpf: Add unwind_goto and unwind_exit insns
  tools/bpf: Remove legacy BPF tools
  bpf: Annotate data races on bpf_lru_node type
  selftests/bpf: Add arena allocation race tests
  bpf: Fix arena race between page free and alloc leading to incoherency
  bpf: Revalidate faulted arena pages before installing user mappings
  ...
2026-10-23 13:08:49 -10:00
Linus Torvalds
c0e8d30137 Modules changes for 7.4-rc1
- Ignore local labels and mapping symbols during module load
 
   These symbols were already ignored during kallsyms address-to-symbol
   lookups. Filter them out earlier during module loading to reduce lookup
   overhead and prevent them from appearing in /proc/kallsyms.
 
 - Fix potentially incorrect access of SetOnce<T> when setting Rust module
   parameters.
 
 - Fix a potential read of an uninitialized count when printing taint
   information for unloaded modules.
 
 - Allocate the kmod argument array using kmalloc_array() in preparation
   for conversion to type-aware allocators.
 
 - Clean up includes in linux/kmod.h
 
   Add explicit includes of linux/umh.h to files that use usermode helpers.
   Then clean up the #include list in linux/kmod.h, notably removing the
   compatibility linux/umh.h include.
 
 - Remove the error-injection.h include from linux/module.h
 
   Add explicit includes of linux/error-injection.h to files that use the
   ALLOW_ERROR_INJECTION() macro and currently rely on it being provided
   indirectly via linux/module.h. Then remove the unnecessary
   linux/error-injection.h include from linux/module.h.
 
 - Replace __MODULE_STRING() with __stringify() in various drivers in
   preparation for removing the former macro.
 
 The changes to several #include lists have been reported to cause trivial
 conflicts in linux-next with the drm, drm-xe, and usb trees.
 -----BEGIN PGP SIGNATURE-----
 
 iQFkBAABCABOFiEEIduBR9MnFA82q/jtumpXJwqY6poFAmrWJvAbFIAAAAAABAAO
 bWFudTIsMi41KzEuMTIsMiwyFBxwZXRyLnBhdmx1QHN1c2UuY29tAAoJELpqVycK
 mOqalOYH/RpwszqX+OuRhf3G9IDokSZFZyiAJLZan3H7jZNb9VBVLYmTTRYF/UE4
 uXKeGAUXZOaUdhVjQi/1LqX3NbDO1NfUCM9sbk3EPal0L6ILbcmkBecXu9JXHxvB
 6sfEAdTMdAn28613wcnbjmdGfEkgHuDZqZeld4dIAtZ+GvLzFz0D+o0zkigCnT4I
 faKU9GLIHJe2Cn5FB40b1+M+IGY9t6bl2+WxVc1rd9oSZXfr8ptE7NPllhiOmOhD
 /aMVpeSlXzo8DYxIhvtZGwDh5NrJglPFdFRXYuHUDLxkWCCFtXRt//LtWv3EpKqp
 dgQUH5QAO5E/+OuycHFLaXOUiKVS0P4=
 =bCLk
 -----END PGP SIGNATURE-----

Merge tag 'modules-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux

Pull module updates from Petr Pavlu:

 - Ignore local labels and mapping symbols during module load

   These symbols were already ignored during kallsyms address-to-symbol
   lookups. Filter them out earlier during module loading to reduce
   lookup overhead and prevent them from appearing in /proc/kallsyms.

 - Fix potentially incorrect access of SetOnce<T> when setting Rust
   module parameters.

 - Fix a potential read of an uninitialized count when printing taint
   information for unloaded modules.

 - Allocate the kmod argument array using kmalloc_array() in preparation
   for conversion to type-aware allocators.

 - Clean up includes in linux/kmod.h

   Add explicit includes of linux/umh.h to files that use usermode
   helpers. Then clean up the #include list in linux/kmod.h, notably
   removing the compatibility linux/umh.h include.

 - Remove the error-injection.h include from linux/module.h

   Add explicit includes of linux/error-injection.h to files that use
   the ALLOW_ERROR_INJECTION() macro and currently rely on it being
   provided indirectly via linux/module.h. Then remove the unnecessary
   linux/error-injection.h include from linux/module.h.

 - Replace __MODULE_STRING() with __stringify() in various drivers in
   preparation for removing the former macro.

* tag 'modules-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/modules/linux:
  drivers: Replace __MODULE_STRING() with __stringify()
  module: Fix uninitialized count read of unloaded taint tracking record
  rust: module_param: Fix potentially incorrect access of `SetOnce<T>`
  module: Remove the error-injection.h include from linux/module.h
  drm/xe: Include error-injection.h for ALLOW_ERROR_INJECTION()
  drm/i915: Include error-injection.h for ALLOW_ERROR_INJECTION()
  syscalls: Include error-injection.h for ALLOW_ERROR_INJECTION()
  net: Include error-injection.h for ALLOW_ERROR_INJECTION()
  block: Include error-injection.h for ALLOW_ERROR_INJECTION()
  module: Bring includes in linux/kmod.h up to date
  time/jiffies: Include linux/sysctl.h for proc_int_u2k_conv_uop(), ...
  umh, treewide: Explicitly include linux/umh.h where needed
  modules/kmod: Allocate argv with kmalloc_array()
  module/kallsyms: Ignore local labels and mapping symbols during module load
  module/kallsyms: Refactor current symbol filtering into is_core_symbol()
  module/kallsyms: Rename is_mapping_symbol() to is_ignored_kernel_symbol()
2026-10-23 09:32:44 -10:00
Linus Torvalds
14785eff40 KEYS: changes for v7.4-rc1
HIGHLIGHTS
 ==========
 
 A patch that Kyle Zeng submitted addresses a critical bug and complements
 the ongoing rhashtable migration. The commit in question is de891c73c1
 ("keys: make keyring indexes independent of kernel addresses").
 
 The index value for the  associative array has been calculated with the
 following formula:
 
 	mult_64x32_and_fold(description + type address + domain address)
 
 By creating a sequence of dummy keys (e.g., "A", "B", "C", ...), it is
 trivial to form a group of equations with a predictable hash function, and
 ultimately break KASLR.
 
 Kyle's solution is based on an ephemeral SipHash key and an atomic 64-bit
 counter, which is encapsulated to a key_index_id(). This function is then
 used to assign identifiers for types and domains, and since the IDs are
 unique for each power on, they are as unique as memory addresses are.
 
 With these ingredients the index value calculation can be changed into
 form, which is not leaking any kernel addresses:
 
 	SipHash(description + type id + domain id)
 
 This is exactly what the Kyle's commit does.
 
 FEATURES AND IMPROVEMENTS
 =========================
 
 - TPM fields were moved from trusted_key_options to the TPM backend.
   They cost memory for non-TPM backends.
 - A TPM trusted key now caches tpm_is_tpm2() at the root of each call
   chain, and passes the result as a parameter. This decreases the amount
   of I/O traffic given that tpm_is_tpm2() starts and stops the chip via
   tpm_try_get_ops() and tpm_put_ops().
 
 BUGS
 ====
 
 - A TPM trusted key corrupted the return value of a failed key unsealing
   operation if the pcrlock feature was used.
 - A TPM 2 trusted key allocated an off-by-four too large buffer for the
   decoded ASN.1 blob coming from keyctl add trusted.
 - Sometimes a TPM 2 trusted key rejected created keys based on the
   TPM2_Create response size, treating them as too large. Now it correctly
   checks the extracted TPM2 key blob size.
 - The keyctl reject operation raced with keyctl restrict_keyring because
   keyring->sem was not held in key_reject_and_link() before accessing
   keyring->restrict_link.
 - keyctl_describe_key() was not holding key->sem while accessing its
   fields, which can lead to use-after-free of a retired key type.
 - find_keyring_by_name() and procfs code were reading the UID from
   key->user->uid instead of key->uid. The latter is the cached value and
   is meant to protect against a use-after-free caused by keyctl chown.
 - search_process_keyrings_rcu() did not properly RCU-dereference the
   authorization key payload, which could cause a null dereference if the
   payload was revoked.
 - keyctl_read_key() checked key->type->read without holding key->sem,
   which can lead to use-after-free if the type is retired. Based on my
   suggestion, this was addressed in __keyctl_read_key(), which already
   did take key->sem.
 -----BEGIN PGP SIGNATURE-----
 
 iHUEABYKAB0WIQRE6pSOnaBC00OEHEIaerohdGur0gUCatjKPgAKCRAaerohdGur
 0iVIAP9N2OG7/93a2WbH14jxbEQv2zWEZlV0lz4b4NdV0qyhBwEArta0xov2A57X
 nGFNGEYOjtOS1WFJlvBetu0G9Uz/TAA=
 =Xkuf
 -----END PGP SIGNATURE-----

Merge tag 'keys-v7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd

Pull keys updates from Jarkko Sakkinen:
 "Highlight:

   - Don't leak local kernel addresses (and complement the ongoing
     rhashtable migration) (Kyle Zeng)

     The index value for the associative array has been calculated with
     the following formula:

	mult_64x32_and_fold(description + type address + domain address)

     By creating a sequence of dummy keys (e.g., "A", "B", "C", ...), it
     is trivial to form a group of equations with a predictable hash
     function, and ultimately break KASLR.

     Kyle's solution is based on an ephemeral SipHash key and an atomic
     64-bit counter, which is encapsulated to a key_index_id(). This
     function is then used to assign identifiers for types and domains,
     and since the IDs are unique for each power on, they are as unique
     as memory addresses are.

     With these ingredients the index value calculation can be changed
     into form, which is not leaking any kernel addresses:

	SipHash(description + type id + domain id)

  Features and improvements:

   - TPM fields were moved from trusted_key_options to the TPM backend.
     They cost memory for non-TPM backends.

   - A TPM trusted key now caches tpm_is_tpm2() at the root of each call
     chain, and passes the result as a parameter. This decreases the
     amount of I/O traffic given that tpm_is_tpm2() starts and stops the
     chip via tpm_try_get_ops() and tpm_put_ops().

  Bugfixes:

   - A TPM trusted key corrupted the return value of a failed key
     unsealing operation if the pcrlock feature was used.

   - A TPM 2 trusted key allocated an off-by-four too large buffer for
     the decoded ASN.1 blob coming from keyctl add trusted.

   - Sometimes a TPM 2 trusted key rejected created keys based on the
     TPM2_Create response size, treating them as too large. Now it
     correctly checks the extracted TPM2 key blob size.

   - The keyctl reject operation raced with keyctl restrict_keyring
     because keyring->sem was not held in key_reject_and_link() before
     accessing keyring->restrict_link.

   - keyctl_describe_key() was not holding key->sem while accessing its
     fields, which can lead to use-after-free of a retired key type.

   - find_keyring_by_name() and procfs code were reading the UID from
     key->user->uid instead of key->uid. The latter is the cached value
     and is meant to protect against a use-after-free caused by keyctl
     chown.

   - search_process_keyrings_rcu() did not properly RCU-dereference the
     authorization key payload, which could cause a null dereference if
     the payload was revoked.

   - keyctl_read_key() checked key->type->read without holding key->sem,
     which can lead to use-after-free if the type is retired. Based on
     my suggestion, this was addressed in __keyctl_read_key(), which
     already did take key->sem"

* tag 'keys-v7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/jarkko/linux-tpmdd:
  keys/trusted_keys: reuse TPM version in option handling
  security: keys: Fix comment of search_process_keyrings_rcu()
  keys/trusted/tpm2: Validate TPM2_Create object sizes separately
  keys/trusted_keys: move TPM-specific fields into struct trusted_key_tpm
  keys: Protect the read method check against type removal
  keys: Avoid owner account dereferences in /proc/keys
  keys: make keyring indexes independent of kernel addresses
  keys: Check the authorization payload in process keyring searches
  keys: Avoid the owner account dereference in named keyring lookup
  keys: Protect the type name while describing a key
  KEYS: Fix key_reject_and_link() race with keyring restriction
  KEYS: trusted: Fix blob allocation size in tpm2_key_decode()
  keys/trusted_keys: return immediately after TPM unseal failure
2026-10-22 10:02:37 -10:00
Linus Torvalds
3815f7d55a Landlock update for v7.4-rc1
-----BEGIN PGP SIGNATURE-----
 
 iIYEABYKAC4WIQSVyBthFV4iTW/VU1/l49DojIL20gUCatjkPhAcbWljQGRpZ2lr
 b2QubmV0AAoJEOXj0OiMgvbS45sBAPNe/CnhCS8x7P8LeZSH80rAs5mg7pmM5AWx
 dKr/n38OAP4l+qqQ4nIZUJqx0qfCuo7hzwX1xnKn+TUdUsNNS/9uBw==
 =EVuG
 -----END PGP SIGNATURE-----

Merge tag 'landlock-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux

Pull Landlock update from Mickaël Salaün:
 "The main change adds composable Landlock controls for namespace types
  and Linux capabilities, thanks to new LSM hooks (merged via the LSM
  tree). A umount race condition is also fixed"

* tag 'landlock-7.4-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
  landlock: Fix superblock use-after-free in release_inode()
  selftests/landlock: Fix snprintf truncation checks in test files
  landlock: Add documentation for capability and namespace restrictions
  samples/landlock: Add capability and namespace restriction support
  selftests/landlock: Add capability restriction tests
  selftests/landlock: Add namespace restriction tests
  landlock: Enforce capability restrictions
  landlock: Enforce namespace use restrictions
  landlock: Wrap per-layer access masks in struct layer_config
  landlock: Rename quiet_masks to quiet_access
2026-10-22 09:58:44 -10:00
Linus Torvalds
bbc48daeca ipe/stable-7.4 PR 20261019
-----BEGIN PGP SIGNATURE-----
 
 iIcEABYIAC8WIQQzmBmZPBN6m/hUJmnyomI6a/yO7QUCata16hEcd3VmYW5Aa2Vy
 bmVsLm9yZwAKCRDyomI6a/yO7fWMAP416s5s3d9o4r/ZiSzs/4ZqoFQcffMlnJAM
 /PbtwC1fKwD/WDlfsk+aydwK8vamTeA0sWI9dkxtxx3a42Lik46ATw4=
 =4oH1
 -----END PGP SIGNATURE-----

Merge tag 'ipe-pr-20261019' of git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe

Pull IPE updates from Fan Wu:

 - Fix an extra empty audit record on enforcement changes

   ipe_audit_enforce() started an audit buffer but logged the state
   change with audit_log(), which emits its own record. Ending the
   unused buffer produced an additional empty AUDIT_MAC_STATUS record
   every time the enforcement state was changed.

 - Keep the name and token tables in sync with their enums

   The audit name tables now use designated initializers, so each name
   stays bound to its enum value, and static assertions on the policy
   parser token tables break the build if an enum value is added without
   a matching token.

 - Constify token_default() and correct a comment about policy text
   ownership, with no functional changes

 - Fix an invalid sgid value in an audit event example in the docs

 - Point the docs to the new IPE website and test suite repository

* tag 'ipe-pr-20261019' of git://git.kernel.org/pub/scm/linux/kernel/git/wufan/ipe:
  ipe: update the project and test suite links
  ipe: fix enforcement audit
  ipe: correct policy text ownership comment
  ipe: check parser token table sizes
  ipe: use designated initializers for audit name tables
  ipe: constify token_default()
  ipe: fix invalid sgid value in audit event documentation
2026-10-22 09:55:12 -10:00
Linus Torvalds
31aa192602 integrity-v7.4
-----BEGIN PGP SIGNATURE-----
 
 iIoEABYKADIWIQQdXVVFGN5XqKr1Hj7LwZzRsCrn5QUCatZSiBQcem9oYXJAbGlu
 dXguaWJtLmNvbQAKCRDLwZzRsCrn5elNAP4zRtdRm2js06sXtJm6fgy54pgXiYpv
 rUIKQeOWsYu7xAD+LmH9IRpNoUnGpoptfm4qtwQD4cxVivkpi7m8DJ57Cg8=
 =2+cF
 -----END PGP SIGNATURE-----

Merge tag 'integrity-v7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity

Pull IMA updates from Mimi Zohar:
  "Cleanup:

   - Update ima_audit_msg() to report errno directly, revert making it a
     wrapper for ima_audit_message(), and remove ima_audit_message()

  Two bug fixes when carrying the IMA measurement list across kexec:

   - Restore the number of violations in the IMA measurement list

   - Reject restoring IMA measurement list record(s) beyond the expected
     buffer size (out-of-bounds)"

* tag 'integrity-v7.4' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: reject a kexec buffer whose declared size exceeds the buffer
  ima: recover number of violations after kexec
  integrity: Replace integrity_audit_message() with integrity_audit_msg()
  integrity: Report error code in integrity_audit_msg() call sites
2026-10-22 09:53:20 -10:00
Linus Torvalds
a804c5742b lsm/stable-7.4 PR 20261016
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmrSkXAUHHBhdWxAcGF1
 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXOXTQ/+LcghZOG72DOeZwDkXIzdD+Ex5Xkf
 kV3EiZ+l6LCy2sGePC5PdHJaX1wQE5N0bHCHh8TMIsfE5b0nbdKJsDiFJVkayTJz
 CE4SpAm8Tup+CBDkwMJ1x3aGYgh4RxbgTR9klsrH2zsehI80sGLE3SYp9+lO3BFp
 Eyf+INgF2GrcBNH3ozQBtME5b0086UC/uWif1vQ3HK4RU6QxWlQg5VB68+XJv9GY
 /wZyJ4bIet8QQ1S2boMQN/RGQHih1qYs8hOeuL+R0Inh6pk59ucgM3qfj9OILWbD
 x4u9ptO7ICvoKlkrzWIfvt+ydM5q9mHozN1qi2i+dy4IiDyBicZ75YCFWIeSOld+
 UGL73NB08g/KT1fOo7WE3lfm/ZAMoR8F0IUScDvMeVLv06NU/rCccPKl+z8bYBuo
 vSbctpHsnSPxpZew1U1FiTavwTUZVTHgPnuGrM28wfV1qsj+y9jebM35GNETolDi
 6fcsVh6Fw/8qCG/V1TVQzahqI0xuA2/BDQE7vFKO87Mmu7EJqNr1J3lgFdmMk7tD
 cZqHhHhSF7MgQz8qkuCB8t2edukXV1Fyzm8tUmA9MeurfQHrhLkwZuRPzKmEz0RB
 HssTyKhmo9cwgLgRFzspnoDIOXcSYqxUNSmz4BOVb9yUMi/d5bRhiZ6JFym19rRr
 9IjSU2ud7x3fXqw=
 =7Dpp
 -----END PGP SIGNATURE-----

Merge tag 'lsm-pr-20261016' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm

Pull lsm updates from Paul Moore:

 - Add LSM hooks, object blobs, and audit records for namespaces

   Add the necessary bits to enable LSMs to enforce access controls on
   the management of various kernel namespaces. While this pull request
   does not contain any in-tree users of these hooks, the Landlock pull
   request for Linux v7.4 will include Landlock support and the next
   merge window will likely include SELinux support as well. Considering
   the development behind these hooks, I expect that BPF LSM developers
   will also be making use of the namespace hooks, if they haven't
   already.

 - Update the inode LSM hooks to include mount idmaps

   This allows LSMs to incorporate the mount ID mapping into their
   access control decisions. While there are no current in-tree users of
   this, it was requested by those developing BPF LSM programs and this
   pull request includes a BPF LSM selftest.

 - Preserve the full 32-bit ioctl command in LSM audit records

   Previously only the low 16 bits were logged, ignoring the direction
   and size information in the upper 16 bits. The pull request also
   includes a Landlock based selftest to verify the full 32-bit ioctl
   value.

 - Ensure we don't call security_backing_file_free() multiple times

   Thankfully we don't have a problem with the current code base, but we
   want to fix this behavior now before it becomes a problem.

 - Clarify that only the current task may access current->cred

   The current code is a bit misleading around safely accessing the cred
   field in a task struct. Through comment and code corrections, this
   pull request clarifies that only the task itself may access its cred
   field.

 - Add SLAB_NO_MERGE to the credential object cache

   Harden the credential cache by ensuring credential objects live on
   dedicated slab pages.

 - Make use of safe memory zero'ing in the LSM Rust bindings

 - Update the docs for the current behavior of /sys/kernel/security/lsm

 - Update the docs for CONFIG_LSM and the "lsm=" command line option

 - Remove unnecessary code

* tag 'lsm-pr-20261016' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm:
  lsm: remove redundant NULL check in security_init()
  selftests/landlock: Check full ioctl commands in audit records
  lsm: Preserve full ioctl commands in audit records
  doc: fix LSM ordering description for /sys/kernel/security/lsm
  doc: describe CONFIG_LSM and lsm= as the selection mechanism
  selftests/bpf: verify mount idmaps reach inode hooks
  lsm: expose mount idmaps to inode hooks
  rust: lsm: replace `core::mem::zeroed` with `pin_init::zeroed`
  cred: prevent slab cache merging for cred_jar
  lsm: don't call security_backing_file_free() multiple times
  lsm: delete duplicate assignment in lsm_prepare()
  lsm: update the BUILD_BUG_ON() in audit_log_lsm_data()
  lsm: add LSM_AUDIT_DATA_NS for namespace audit records
  lsm: add LSM blob and hooks for namespaces
  ns: Free anonymous mount namespaces via ns_common_free()
  cred: clarify that task_struct::cred is only for the current task
2026-10-20 20:04:07 -10:00
Linus Torvalds
331eadd85f selinux/stable-7.4 PR 20261015
-----BEGIN PGP SIGNATURE-----
 
 iQJIBAABCgAyFiEES0KozwfymdVUl37v6iDy2pc3iXMFAmrRAQIUHHBhdWxAcGF1
 bC1tb29yZS5jb20ACgkQ6iDy2pc3iXPjzBAAhBwzyxD47NquFO6w6dHj95wol7t/
 sxiWyNMLIPHsXr5RjbqS/EIkCS9OM0ZPRSKFAY/x1ddTJRr2KIQiaUPI1cf+VsMG
 QeGYd9p5Kp00jopa8Mj+2No9TvJZoNMTEyNYgtBQWCNUwF+dnYV0/c42IoHNeuOm
 5+BvqAIL32sEHHEtDeyconNJq4SLhsh75jC0jZtGSIbk3Y33a8q+4WkLc6nLzE7f
 AY5G4BDgt4z+Y7isMjDf1ApItyvDeHm4HP5gzu/YKUEF0D25UPiI+/eQhBAKdIEW
 +Y6v2NkN/0bYFGX/tKcKBAUb4OdYPcqA4B+H+5y03m/BuUxkqX3q5b3n4uPuL5Bl
 2nKVHtie/jjBEKTLlmP/bdivDPpf8V7Ljy/9baqrRuQSoUtxU9dd/dV+Ae08iKY4
 m1l6Kw2SjxoDNRRwaXJAA0oYCfl5T0OY3ZSaZCUnBLv7sNw3AZzop1c1FFRaLeeJ
 KGYju9cB+XsvOWTdkV7xGj6JFJpazcMSm6HPwkEEoXHpnuA842ErBpjozPpaTPsR
 i7EW1a/ohx2PXwWBxttYUY6IC8IW/d7vMTmR4hxkzILq3L0IMhdBnKvGsUWfvlrf
 5kqUEvxN+6SbhRhg2Jm9MRtW7/Tt2w8Ev2smb8B6zO1VcYDzEAgojtlymoS+itYK
 psYNddDIrkfSkpw=
 =pp5e
 -----END PGP SIGNATURE-----

Merge tag 'selinux-pr-20261015' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux

Pull selinux updates from Paul Moore:

 - Continue to improve the load time validation of SELinux policies

   While SELinux policy loading remains a privileged operation, we
   continue the recent trend of hardening the policy parsing and
   validation code in the kernel to ensure that invalid, or poorly
   formatted policies are rejected at load time.

 - Correctly incorporate "neveraudit" into the xperms code

   This change aligns the xperms neveraudit handling with the
   conventional permission handling code, exiting early from the SELinux
   auditing code when neveraudit is enabled for the domain.

 - Mark the selinuxfs "status" and "policy" files immutable

   These are read-only kernel/userspace interfaces that could
   successfully be opened at the VFS layer through the use of
   CAP_DAC_OVERRIDE. With this pull request we are marking these two
   files as immutable so that the requests to open these file with write
   permissions now fail at the VFS layer. This also allows us to drop
   some of our mmap() checks around write permissions as the VFS will
   now also handle this for us.

   The existing SELinux permissions checks remain untouched.

 - Convert the selinuxfs inode numbers to u64

   Bring selinuxfs current with other filesystems in using u64 for inode
   numbering as opposed to the architecture dependent unsigned long.

 - Constify a number of the SELinux AVC function parameters

 - Remove a SELinux MLS function that was no longer used

* tag 'selinux-pr-20261015' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: validate permissive and neveraudit map types at load
  selinux: validate user MLS range and default level at load
  selinux: bounds-check role and user membership bitmaps at load
  selinux: check neveraudit in avc_xperms_audit_required()
  selinux: bounds-check filename transition source types at load
  selinux: reject duplicate symbol values during policy load
  selinux: reject a policy that both rejects and allows unknown classes
  selinux: constify avc function parameters
  selinux: avoid 64-bit division of inode numbers
  selinux: mark status and policy inodes as immutable, drop status mmap write checks
  selinux: remove unused mls_setup_user_range()
  selinux: convert selinuxfs inode numbers from unsigned long to u64
  selinux: tighten policydb_context_isvalid() checks
2026-10-20 19:42:14 -10:00
Linus Torvalds
95615dd9ff Crypto library updates for 7.4
- Migrate the x86 and riscv optimized implementations of various AES
   modes (ECB, CBC, CBC-CTS, CTR, XCTR, XTS) into lib/crypto/.
 
   This makes the library APIs be properly accelerated on these
   architectures, while still accelerating crypto_skcipher as well.
 
   It removes a lot of redundant glue code, since the crypto API
   boilerplate no longer needs to be duplicated for these architectures.
 
   It also fixes the longstanding issue where optimizations for these
   AES modes were disabled by default on these architectures.
 
 - Optimize AES-XTS on SPARC64 using the SPARC crypto opcodes
 
 - Move the SipHash code into lib/crypto/
 
 - Update the ChaCha and Poly1305 functions to take size_t lengths,
   resolving issues where lengths over INT_MAX were mishandled
 
 - Make frame pointer unwinding work properly in some of the x86
   assembly functions, by following the standard %rbp convention
 
 - Add helper functions for zeroizing structs
 
 - Make a few documentation improvements
 -----BEGIN PGP SIGNATURE-----
 
 iIoEABYIADIWIQSacvsUNc7UX4ntmEPzXCl4vpKOKwUCatTfbBQcZWJpZ2dlcnNA
 a2VybmVsLm9yZwAKCRDzXCl4vpKOK9yhAP0RU5ofTuvc8jj2o02JlXnnxwzda+zh
 tpJYOIHfW6+2UwD/XjbNgngca3ByRL2f3rt2xdSaqSIjmRMP4Blkgeazsw4=
 =zs1E
 -----END PGP SIGNATURE-----

Merge tag 'libcrypto-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux

Pull crypto library updates from Eric Biggers:

 - Migrate the x86 and riscv optimized implementations of various AES
   modes (ECB, CBC, CBC-CTS, CTR, XCTR, XTS) into lib/crypto/.

   This makes the library APIs be properly accelerated on these
   architectures, while still accelerating crypto_skcipher as well.

   It removes a lot of redundant glue code, since the crypto API
   boilerplate no longer needs to be duplicated for these architectures.

   It also fixes the longstanding issue where optimizations for these
   AES modes were disabled by default on these architectures.

 - Optimize AES-XTS on SPARC64 using the SPARC crypto opcodes

 - Move the SipHash code into lib/crypto/

 - Update the ChaCha and Poly1305 functions to take size_t lengths,
   resolving issues where lengths over INT_MAX were mishandled

 - Make frame pointer unwinding work properly in some of the x86
   assembly functions, by following the standard %rbp convention

 - Add helper functions for zeroizing structs

 - Make a few documentation improvements

* tag 'libcrypto-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/ebiggers/linux: (49 commits)
  lib/crypto: md5: remove unused header
  lib/crypto: mips/chacha: Handle lengths of 2 GiB or more
  lib/crypto: arm/chacha: Handle lengths of 2 GiB or more in scalar code
  lib/crypto: chacha: Use size_t length
  lib/crypto: poly1305: Use size_t length
  lib/crypto: x86/sha512: Follow the normal %rbp convention
  lib/crypto: x86/sha256: Follow the normal %rbp convention
  lib/crypto: x86/sha1: Follow the normal %rbp convention
  lib/crypto: chacha20poly1305: zeroize state in __chacha20poly1305_decrypt
  lib/crypto: sparc/aes-xts: Add optimization using the AES opcodes
  lib: Move SipHash into lib/crypto/
  lib/crypto: x86/aes-ctr: Remove some unreachable code
  crypto: x86/aesni-intel - Add transitional selections
  crypto: aes - Boost priority of encryption modes further
  lib/crypto: x86/aes: Set RNDKEY in aes_cbc_encrypt_aesni()
  lib/crypto: riscv/aes-xts: Migrate optimized code into library
  lib/crypto: riscv/aes-ctr: Migrate optimized code into library
  lib/crypto: riscv/aes-cbc: Migrate optimized code into library
  lib/crypto: riscv/aes-ecb: Migrate optimized code into library
  lib/crypto: riscv/aes: Pass key struct to assembly code
  ...
2026-10-20 15:38:53 -10:00
Srish Srinivasan
722658cac4 keys/trusted_keys: reuse TPM version in option handling
Determine the TPM version once in the seal and unseal paths, and reuse
it when allocating and parsing trusted key options.

This reduces the number of fallible calls to tpm_is_tpm2() and avoids
unnecessary I/O between the kernel and the TPM.

Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20261005062732.140733-1-ssrish@linux.ibm.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:15:40 +03:00
Thomas Huth
bbebc81e7e security: keys: Fix comment of search_process_keyrings_rcu()
search_my_process_keyrings() has been renamed to search_cred_keyrings_rcu()
in commit e59428f721 ("keys: Move the RCU locks outwards from the keyring
search functions"), but one spot has been missed in a comment.

Signed-off-by: Thomas Huth <thuth@redhat.com>
Reviewed-by: Jinjie Ruan <ruanjinjie@huawei.com>
Link: https://lore.kernel.org/r/20260928072024.91664-1-thuth@redhat.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:15:40 +03:00
Srish Srinivasan
9dbaf2346d keys/trusted/tpm2: Validate TPM2_Create object sizes separately
TPM2_Create returns outPrivate, outPublic, creationData, creationHash and
creationTicket in its response parameter area. However, only outPrivate and
outPublic are included in the trusted key blob. The size of the blob is
therefore not determined by the size of the complete response parameter
area.

tpm2_seal_trusted() currently compares the size of the complete response
parameter area against MAX_BLOB_SIZE. This can reject a valid response
when the remaining response outputs cause the entire response parameter
area to exceed MAX_BLOB_SIZE, even though the outPrivate and outPublic
TPM2B structures consumed by tpm2_key_encode() remain small enough to be
encoded in the key blob.

This is observed when creating larger trusted keys using the swtpm TPM 2.0
emulator backed by libtpms.

For example, requesting a 113-byte key succeeds, 114 fails.

~$ keyctl add trusted trusted_key1 "new 113 keyhandle=0x81000001" @u
520504613
~$ keyctl add trusted trusted_key2 "new 114 keyhandle=0x81000001" @u
add_key: Argument list too long
~$

Remove the MAX_BLOB_SIZE check on the complete response parameter area.
Instead, use the response length passed to tpm2_key_encode() to validate
that the outPrivate and outPublic TPM2B structures are fully contained
in the response before accessing them.

Previously, a response parameter area larger than MAX_BLOB_SIZE was
rejected with -E2BIG before ASN.1 encoding. With this change, if the
resulting encoded blob does not fit in payload->blob, the error returned by
asn1_encode_sequence() is propagated instead.

Also, use scope-based cleanup to simplify resource management.

Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Link: https://lore.kernel.org/r/20260926184203.479203-1-ssrish@linux.ibm.com
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:15:40 +03:00
Srish Srinivasan
d909d83901 keys/trusted_keys: move TPM-specific fields into struct trusted_key_tpm
The trusted_key_options struct contains TPM-specific fields (keyhandle,
keyauth, blobauth_len, blobauth, pcrinfo_len, pcrinfo, pcrlock, hash,
policydigest_len, policydigest, and policyhandle). This leads to the
accumulation of backend-specific fields in the generic options structure.

Define struct trusted_key_tpm and move the TPM-specific fields there. Store
a pointer to it in the private member of struct trusted_key_options.

Signed-off-by: Srish Srinivasan <ssrish@linux.ibm.com>
Reviewed-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260912062950.279104-3-ssrish@linux.ibm.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:15:40 +03:00
Cen Zhang
925c84e3cc keys: Protect the read method check against type removal
keyctl_read_key() checks key->type->read without holding key->sem.
A reference keeps the key alive, but does not pin the module containing
its type. A surviving RxRPC key can therefore be read while AF_RXRPC
is being unloaded:

  KEYCTL_READ task                    Module unload and key GC
  ----------------                   ------------------------
  lookup_user_key()
  permission / possession checks
  load key->type
                                     af_rxrpc_exit()
                                       unregister_key_type()
                                         GC: down_write(key->sem)
                                         GC: retype to key_type_dead
                                         GC: up_write(key->sem)
                                       unregister_key_type() returns
                                     free_module()
  read saved type's read member

The final access can read freed module storage. The read invocation in
__keyctl_read_key() is already protected by key->sem, but the earlier
method check is outside that critical section.

Move the method check into __keyctl_read_key(), after key_validate() and
under its existing read hold on key->sem. The check and invocation then
use the same protected type for length queries and every read retry.
The GC cannot retype the key until the semaphore is released, and type
unregistration waits for that GC pass before the module can be freed.

Return -EOPNOTSUPP when validation succeeds and the type has no read
method. A temporary buffer may now be allocated before this result;
allocation and copying to userspace remain outside the semaphore.

Assisted-by: LLM
Cc: stable@vger.kernel.org # v5.10+
Fixes: d3ec10aa95 ("KEYS: Don't write out to userspace while holding key semaphore")
Suggested-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Reviewed-by: David Howells <dhowells@redhat.com>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0010-v7-fc85721ff5cfb9e33ac6@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:14:52 +03:00
Cen Zhang
30a9dac7c6 keys: Avoid owner account dereferences in /proc/keys
The namespace filters in find_ge_key() and key_serial_next() read
key->user->uid while traversing the serial tree under key_serial_lock.
That lock keeps the key allocated, but it does not protect the separate
key_user from ownership changes.

A /proc/keys read reaches find_ge_key() through proc_keys_start(), and
key_serial_next() through proc_keys_next(). The lock stays held until
proc_keys_stop().

A successful privileged KEYCTL_CHOWN on the same key replaces key->user
under key->sem and drops the old owner's reference after releasing the
semaphore. If that was the old dynamic key_user's last reference, a
/proc/keys reader can access freed memory:

    /proc/keys reader                   KEYCTL_CHOWN
    proc_keys_start()                    keyctl_chown_key()
      spin_lock(key_serial_lock)          down_write(key->sem)
      find_ge_key()
        old = minkey->user
                                          zapowner = key->user
                                          key->user = newowner
                                          key->uid = uid
                                          up_write(key->sem)
                                          key_put(key)
                                          key_user_put(zapowner)
                                            kfree(zapowner)
        read old->uid -> use-after-free
    proc_keys_stop()
      spin_unlock(key_serial_lock)

Use the inline key->uid in both filters, following the approach already
used by find_keyring_by_name(). The serial-tree lock keeps the containing
key alive, so filtering no longer depends on the quota owner's lifetime.
This also uses the same owner UID as proc_keys_show() and the permission
check.

For thread keyrings, key_fsuid_changed() can update key->uid without
changing the quota owner. The filters now follow that current owner UID,
including when its namespace mapping differs from the quota owner's.

Fixes: 454804ab03 ("keys: make procfiles per-user-namespace")
Assisted-by: LLM
Suggested-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-keys-proc-owner-uid-followup-20261017-v2-8f8f34a41eb1bbb94ef0@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:13:07 +03:00
Kyle Zeng
de891c73c1 keys: make keyring indexes independent of kernel addresses
KEYCTL_READ returns the serial numbers in a keyring in associative-array
traversal order.  The first word of the index is a public, deterministic
hash of the type pointer, domain pointer and description.  An unprivileged
user can therefore insert keys with known descriptions, predict their
order for each possible KASLR slide, and recover the kernel image address.
On an x86-64 build with 16 MiB alignment, 45 user keys suffice to
distinguish the candidate slides.

Remove the addresses from the whole index, not just its first hash word.
Assign each key type and domain a nonzero 64-bit ID and hash those IDs and
the description with a once-initialized SipHash key.  Use the full IDs in
the later index chunks as well.  Truncating or hashing the IDs there would
lose the guarantee that distinct type/domain/description tuples have a
differing index bit.

Allocate IDs lazily since private key types need not be registered.  Cache
them in the index key so tree walks and copies of an existing index do not
need to dereference a type descriptor that may have been unregistered.
Keep the 32-bit chunk layout and diff_objects() bit offsets consistent,
and retain the separate root slot for keyrings used by recursive search.
The key comparison, permissions and userspace data format are unchanged;
only the address-dependent in-memory ordering is replaced.

Cc: stable@vger.kernel.org
Fixes: b2a4df200d ("KEYS: Expand the capacity of a keyring")
Assisted-by: Codex:gpt-6-astra
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20261013231251.56170-1-kylebot@openai.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:13:07 +03:00
Cen Zhang
0a0ec45bf5 keys: Check the authorization payload in process keyring searches
An authorization payload and its saved credentials must remain valid
while search_process_keyrings_rcu() searches the requestor's keyrings.
The function validates the authorization key, then separately loads
payload.data[0] and unconditionally reads rka->cred. Validation does
not prevent request_key_auth_revoke() from clearing the payload.

A request-key helper can assume authority and fork a descendant that
inherits the authorization key. If the descendant misses in its own
keyrings, it falls back to the saved requestor credentials. Successful
target instantiation invalidates the authorization key without clearing
the payload. After the helper exits, UMH_WAIT_PROC returns to the
requester, which calls complete_request_key() and revokes that key.

With the descendant paused after validation, the paths can interleave
as follows:

  1. The descendant enters search_process_keyrings_rcu() under RCU and
     key_validate() succeeds.
  2. The helper instantiates the target, invalidates the authorization
     key, and exits.
  3. The requester resumes from UMH_WAIT_PROC, calls
     complete_request_key(), and revokes the authorization key.
     request_key_auth_revoke() sets its payload pointer to NULL.
  4. The descendant loads NULL and dereferences rka->cred.

This NULL dereference can oops the kernel. RCU delays payload disposal
but does not prevent the pointer from being cleared.

Load the payload with dereference_key_rcu() and require a non-NULL
result before validating the authorization key and searching its saved
credentials. A non-NULL payload and its credentials remain alive for
the caller's RCU read-side section; a cleared payload skips the fallback
search and follows the existing error selection.

KASAN report as below:

    Oops: general protection fault, probably for non-canonical address 0xdffffc0000000005: 0000 [#1] SMP KASAN NOPTI
    KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
    RIP: 0010:search_process_keyrings_rcu+0x32b/0x790

Cc: stable@vger.kernel.org
Fixes: e59428f721 ("keys: Move the RCU locks outwards from the keyring search functions")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0004-v3-598361863b76bc25d58d@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:13:07 +03:00
Cen Zhang
51409aaa01 keys: Avoid the owner account dereference in named keyring lookup
Named keyring lookup must keep the storage containing the owner UID
alive through the namespace mapping check.  find_keyring_by_name()
reads keyring->user->uid under keyring_name_lock, but that lock protects
the keyring's name entry and allocation, not its separate key_user.

A named session-keyring join can overlap a privileged KEYCTL_CHOWN on
another CPU.  If the keyring holds the last reference to its old dynamic
key_user and the ownership transfer succeeds, the following ordering is
possible:

    Named join                         Chown
    find_keyring_by_name()              keyctl_chown_key()
      read_lock(keyring_name_lock)       down_write(key->sem)
      load old keyring->user
                                         replace key->user and key->uid
                                         up_write(key->sem)
                                         key_put(key)
                                         key_user_put(old user): free
      read old user->uid
      read_unlock(keyring_name_lock)

Chown neither takes keyring_name_lock nor key_session_mutex, so it can
free the old account between the pointer load and the UID read.  The
lookup then reads freed memory even though the keyring itself is alive.

Use keyring->uid for the mapping check.  key_alloc() initializes this
inline owner UID and keyctl_chown_key() updates it on chown.
The existing name lock keeps its containing keyring allocated throughout
the check, so lookup no longer depends on the account's lifetime.  This
also matches the owner UID used by the permission check.

KASAN report as below:

    BUG: KASAN: slab-use-after-free in find_keyring_by_name+0x577/0x5d0
    Read of size 4 at addr ffff8881128ae2ec by task keycase/500

Cc: stable@vger.kernel.org
Fixes: 2ea190d0a0 ("keys: skip keys from another user namespace")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0002-v3-2baa8cad2bb554364e10@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:13:07 +03:00
Cen Zhang
fced7238b7 keys: Protect the type name while describing a key
keyctl_describe_key() must keep the key type's name alive until
kasprintf() has consumed it. The retained key reference keeps the key
and its description alive, but does not pin the module providing its
type. The name is passed to kasprintf() without holding key->sem.

kvasprintf() uses the saved name pointer in two formatting passes, with
a GFP_KERNEL allocation between them. With AF_RXRPC=m, a task that
passes View permission before type retirement can overlap a privileged
module unload in this order:

1. KEYCTL_DESCRIBE looks up the key, saves key->type->name in the
   kasprintf() arguments and completes the first formatting pass.
2. While the formatter is delayed before its second pass,
   af_rxrpc_exit() calls unregister_key_type(), which removes the type
   from the registry and waits for key_gc_keytype().
3. The collector takes key->sem for writing, retypes the retained key
   to key_type_dead and completes retirement. Unregistration and module
   exit return, allowing free_module() to release the type and name.
4. The formatter resumes its second pass and reads the saved name from
   released module storage, which can fault in string().

Hold key->sem for reading across kasprintf(). The collector then cannot
retype the key or complete retirement until both formatting passes have
finished. If retirement wins the lock first, formatting uses the core
key_type_dead name instead. Release the semaphore immediately after
kasprintf(), including on allocation failure, before copying to
userspace.

Oops report as below:

    BUG: unable to handle page fault for address: fffffbfff8054794
    #PF: supervisor read access in kernel mode
    #PF: error_code(0x0000) - not-present page
    RIP: 0010:string+0x23f/0x470
    Call Trace:
     vsnprintf+0x330/0x1110

Cc: stable@vger.kernel.org
Fixes: aa9d443789 ("KEYS: Fix the size of the key description passed to/from userspace")
Assisted-by: LLM
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/pm-key-management-objects-candidate-0009-v4-6b537c5732fd957c33fa@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:13:07 +03:00
Adrian Martinez
0b157166e6 KEYS: Fix key_reject_and_link() race with keyring restriction
The restrict_link check in key_reject_and_link() is done before taking
the keyring semaphore, racing with a concurrent keyring_restrict()
that installs the restriction while holding the semaphore in write
mode.

Move the check to after __key_link_lock(), so it is done under the
semaphore, matching the pattern used in __key_create_or_update().

Cc: stable@vger.kernel.org
Fixes: 5ac7eace2d ("KEYS: Add a facility to restrict new links into a keyring")
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Signed-off-by: Adrian Martinez <adrimg3196@gmail.com>
Link: https://lore.kernel.org/r/CACO1+RT+m==BY+ZPkE+fo536D0qu3wog4xE1dfuXQ56g+=Qv=A@mail.gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-10-20 18:13:06 +03:00
Günther Noack
3e271a27c4
landlock: Fix superblock use-after-free in release_inode()
Without this fix, release_inode() (task 1) can race with a umount
operation in hook_sb_delete() (task 2).  The order of operations in
which the race occurs is:

* task 2: hook_sb_delete() arrives at the end of the function, waiting
  for landlock_superblock(sb)->inode_refs to become zero.
* task 1: release_inode(): does atomic_long_dec_and_test(), decrementing
  inode_refs to zero.
* task 2: gets woken up through some other means, sees that inode_refs
  is zero and returns.  The caller is the unmount operation and proceeds
  to release the superblock.
* task 1: Runs wake_up_var(&landlock_superblock(sb)->inode_refs),
  *dereferencing the sb_security on the freed-up superblock*.

Notably, wake_up_var() does not dereference the pointer passed to it,
and only uses it to determine an overapproximated set of tasks to wake
up. So while it's potentially possible for an attacker to provide a
different value for that pointer, this only results in the wrong set of
tasks getting woken up, and in this scenario, no further tasks are
actually waiting.

Nevertheless, KASAN detects it as a slab-use-after-free read on
sb->s_security:

  BUG: KASAN: slab-use-after-free in release_inode+0x196/0x290
  Read of size 8 at addr ffff888103b6c0a8 by task repro/217
   release_inode+0x196/0x290
   landlock_put_object+0x71/0x90
   landlock_free_rules+0x38/0xc0
   landlock_put_ruleset+0x47/0x130
   fop_ruleset_release+0x33/0x40
   __fput+0x305/0x780
  Freed by task 54:
   kfree+0x11c/0x390
   process_scheduled_works+0x766/0xe50
   worker_thread+0x7bc/0xb20

The fix is to determine &landlock_superblock(inode->i_sb)->inode_refs only once
earlier in release_inode(), and later use that precalculated address for the
wake_up_var() call, without having to dereference through the superblock.

Cc: stable@vger.kernel.org
Fixes: cb2c7d1a17 ("landlock: Support filesystem access-control")
Assisted-by: LLM
Signed-off-by: Günther Noack <gnoack@google.com>
Link: https://patch.msgid.link/20261006105847.2541190-1-gnoack@google.com
Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-10-20 16:47:24 +02:00
Mickaël Salaün
97c8386f1d
landlock: Enforce capability restrictions
Add Landlock enforcement for capability use via the LSM capable hook.
This lets a sandboxed process restrict which Linux capabilities it can
exercise, using LANDLOCK_PERMISSION_CAPABILITY_USE and per-capability
rules.

The check is a flat per-layer allowed-capabilities test, with no
domain-ancestry bypass, no cross-namespace discriminant, and no
dependency on the target user namespace.  These categorical denials
return -EPERM, like the namespace permission introduced by the previous
commit, and they mirror its per-capability allowed and quiet masks, so
LANDLOCK_ADD_RULE_QUIET stays rejected for this rule type.  Successful
capability rules and denials are traced as the previous commit
describes.

Enforce only at capability exercise time rather than modifying the
credential's capability sets.  Modifying them would give capget(2) an
accurate view of usable capabilities, but no LSM other than commoncap
does so; Landlock follows that convention.  A sandboxed process inside a
user namespace therefore sees all capabilities via capget(2) but
receives -EPERM when attempting to use one that is denied.

An earlier design bypassed this hook for namespace management through a
domain-ancestry comparison with the namespace creator's stored Landlock
domain.  That made a Landlock decision depend on kernel namespace state,
and the ns != cred->user_ns heuristic did not accurately identify
namespace-management operations.  The flat, namespace-agnostic check
instead enforces capability and namespace restrictions independently;
creating a non-user namespace requires an allowed CAP_SYS_ADMIN even
when combined with CLONE_NEWUSER in one unshare().

Cc: Christian Brauner <brauner@kernel.org>
Cc: Günther Noack <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Serge E. Hallyn <serge@hallyn.com>
Link: https://patch.msgid.link/20261014082718.1435842-5-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-10-20 16:47:20 +02:00
Mickaël Salaün
15dd86021b
landlock: Enforce namespace use restrictions
Add Landlock enforcement for namespace use through the LSM
namespace_init and namespace_install hooks.  This lets a sandboxed
process restrict which namespace types it can create, join, or acquire a
file descriptor for, using LANDLOCK_PERMISSION_NAMESPACE_USE and
per-type rules.

Introduce the handled_permissions field in struct landlock_ruleset_attr:
each permission gates every use of a kernel-defined category (CLONE_NEW*
namespace types, CAP_* capabilities) with complete deny-by-default
coverage, so unknown member values need no validation, being denied
until a rule allows them.  This UAPI extension advances the Landlock ABI
from 11 to 12.

There is no domain-ancestry bypass and no namespace-creator tracking,
only a flat per-layer allowed-types bitmask: hook_namespace_init()
covers creation through clone(2), unshare(2), open_tree(2) and
fsmount(2), and hook_namespace_install() covers setns(2).  Each
permission hook maps its member mask explicitly in the shared permission
walker, which warns and denies if a future caller omits that mapping.
These categorical denials return -EPERM, matching Landlock's scope and
mount-topology denials rather than its object-access -EACCES convention.

struct permission_masks is forced to eight bytes with __packed and
__aligned because it must eventually hold both the eight namespace types
and all capabilities, and because m68k GCC otherwise packs its u64
bitfields at byte granularity, making the structure smaller than
sizeof(u64).  Carrying it grows struct layer_config from 4 to 16 bytes,
so the largest 16-entry domain FAM grows from 64 to 256 bytes.

The permissions selector keeps the rule attribute self-describing:

- User space can mask it against handled_permissions, as it masks
  allowed_access against handled_access_fs, so a program built against
  newer headers still adds the rules an older kernel supports.

- It tells apart two attributes that share the same three-u64 layout.
  Unknown member bits are ignored, so without it a mismatched rule type
  would apply a capability mask as namespace types.

- It leaves room for a rule to carry several permissions, or for another
  rule type to key the same permission differently.

The rule also carries a quiet_namespace_types bitmask that suppresses
audit submission for denied members without granting them.  A sandbox
knowingly running a caller that probes a type it will never be granted
would otherwise flood the audit log and drown the surprising denials
that matter.  Quiet is per-member rather than a coarse per-category
ruleset bit, so a sandbox can silence CLONE_NEWNET while still auditing
CLONE_NEWUTS; making it the complement of the allowed set would be
broad, could not audit a member that is neither allowed nor explicitly
quieted, and would auto-hide members added by future kernels.  It is a
per-rule bitmask rather than the LANDLOCK_ADD_RULE_QUIET flag and the
ruleset quiet_access_* masks, which suit the unbounded rb-tree objects
of filesystem and network rules, so that flag is rejected here.  Only
the youngest denying layer's quiet mask decides, so a parent cannot
silence a denial made by a deeper layer.

Trace the handled permission mask, every successful namespace rule, and
namespace denials.  Successful effective no-ops advance the version, and
quiet denials remain trace-visible with logged=0.  The denial event
takes the blockers argument of the filesystem and network events and
records the same blockers_type and blockers_access fields, so one filter
expression spans the mask-bearing denial events.  Handled and rule
permission masks may contain permissions from multiple domains in one
field, so their names are domain-qualified, such as namespace.use.  A
blocker is already interpreted in the domain supplied by the audit
prefix or denial event, so it retains the bare action name use, matching
existing access blockers such as read_file.

User namespace creation does not require capabilities, so Landlock can
restrict it directly.  Non-user namespace types require CAP_SYS_ADMIN
before the Landlock check is reached; when the capability permission
added by the next commit is also handled, both must allow the operation.

Cc: Christian Brauner <brauner@kernel.org>
Cc: Günther Noack <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Cc: Serge E. Hallyn <serge@hallyn.com>
Link: https://patch.msgid.link/20261014082718.1435842-4-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-10-20 16:47:19 +02:00