Commit Graph

7019 Commits

Author SHA1 Message Date
Linus Torvalds
a51ec5e8e5 Merge tag 'integrity-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity
Pull integrity updates from Mimi Zohar:

 - TPM initialization is sometimes delayed until deferred_probe_initcall

   Since ordering is not guaranteed within the same initcall level, IMA
   may initialize before the TPM and fall back to TPM-bypass mode. A new
   config option, CONFIG_IMA_INIT_LATE_SYNC, allows those building the
   kernel to defer IMA initialization to late_initcall_sync, accepting
   the integrity risk of missing early measurements in exchange for
   avoiding TPM-bypass mode.

 - The raw policy rules are now measured, as well as the complete
   policy, closing a gap in integrity measurement coverage

* tag 'integrity-v7.3' of git://git.kernel.org/pub/scm/linux/kernel/git/zohar/linux-integrity:
  ima: measure userspace policy writes before parsing
  ima: add critical data measurement for loaded policy
  security: ima: rename boot_aggregate when ima is initialised at late_sync
  security: ima: introduce IMA_INIT_LATE_SYNC option
  security: lsm: allow LSMs to register for late_initcall_sync init
2026-08-19 17:17:17 -07:00
Linus Torvalds
cbad8981fa Merge tag 'Smack-for-7.3' of https://github.com/cschaufler/smack-next
Pull smack updates from Casey Schaufler:

 - Spelling fix

 - Code optimization in smackfs

 - Fix credential mis-uses

 - Place limits on two of the smackfs interfaces

* tag 'Smack-for-7.3' of https://github.com/cschaufler/smack-next:
  smack: fix cred UAF in smack_file_send_sigiotask()
  smack: restrict smackfs/{direct,mapped} values to 0-255
  smack: deduplicate smackfs/{direct,mapped} file_operations
  smack: show msgrcv() subject task in audit
  smack: fix incorrect task context in smack_msg_queue_msgrcv
  security: smack: fix spelling mistake
  smack: simplify write handlers of sysfs entries
  Smack: Fix error in capability bypass
2026-08-19 16:51:39 -07:00
Linus Torvalds
09005a6398 Merge tag 'lsm-pr-20260814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm
Pull LSM updates from Paul Moore:

 - Remove task_euid()

   The task_euid(), and Rust counterpart, was never widely used, for
   good reason, and now that the only user is gone we're removing it to
   rid ourselves of both dead and funky code.

 - Documentation improvements

   Correct some of the kdoc comments for security_task_prctl() and
   clarify the rust comments on task UID accessors.

 - Fix a memory leak in the LSM syscall selftests

* tag 'lsm-pr-20260814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/lsm:
  selftests/lsm: Fix memory leak in attr_lsm_count
  cred: delete task_euid()
  rust: task: clarify comments on task UID accessors
  lsm: clarify security_task_prctl() hook documentation
2026-08-19 16:28:23 -07:00
Linus Torvalds
4253eb09d2 Merge tag 'selinux-pr-20260814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux updates from Paul Moore:

 - Convert a __get_free_page() call into a kmalloc() call

   We had some very old code that called out to __get_free_page() for
   allocating a pathname. There is no reason this couldn't be done with
   a call to kmalloc() so we've done the conversion and now there is one
   less __get_free_page() caller in the kernel.

 - Limit the number of retired/unknown DCCP netlink messages

   While DCCP is gone from the kernel, there are still userspace tools
   which try to talk to the kernel about DCCP sockets which were
   generating SELinux related log noise (unrecognized netlink message).
   This pull request both limits the log messages to just the first
   instance and also explains to the user that DCCP support has been
   removed.

 - Convert the SELinux strlcat() calls to seq_buf_XXX() calls

   As part of the effort to drop the strlcat() API from the kernel, the
   SELinux/IMA code was converted over to using seq_buf_XXX() calls.

 - Only calculate the SELinux IMA configuration string length once

   Previously each call to generate a SELinux configuration string for
   IMA would have to calculate the length of the string. While the
   contents of the string will likely change over the lifetime of the
   system, the length of the string will not. Calculate the string
   length once at boot and reuse the length value throughout the
   lifetime of the system.

 - Further validation of the SELinux policy at policy load time

   Perform additional sanity checks on the policy constraints and types.

 - Proper cleanup and error handling for selinuxfs init failures

   We were not properly cleaning up some state in the case where
   selinuxfs fails to initialize properly. It's somewhat of an academic
   exercise as a failure to initialize selinuxfs will cause the system
   to fail on boot, but it's arguably better to make sure we do things
   the proper way.

 - Various code cleanups

   Convert integer flags to boolean types and drop an uncessary goto
   from the SELinux code.

* tag 'selinux-pr-20260814' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: validate constraint expression attr and op at load time
  selinux: compute the IMA configuration settings string length once at boot
  selinux: replace strlcat() with seq_buf in selinux_ima_collect_state()
  selinux: suppress warning flood for retired DCCP netlink messages
  selinux: tighten type validation during policy load
  selinux: drop unnecessary goto and label from avc_alloc_node()
  selinux: convert int flags to bool flags in ss/services.c
  selinux: clean up selinuxfs resources on init failure
  selinux: hooks: use kmalloc() to allocate path buffer
2026-08-19 16:24:46 -07:00
Jann Horn
fedc88e38c smack: fix cred UAF in smack_file_send_sigiotask()
When inspecting the credentials of another task, objective credentials
(->real_cred, accessed with __task_cred()) must always be used.

Accessing ->cred on a non-current task is forbidden unless that task is
being created or destroyed; a task is allowed to change its own ->cred
pointer with no synchronization, and changing ->cred should only affect the
current syscall.

smack_file_send_sigiotask() was accessing both sets of credentials: First
tsk->cred, then __task_cred(tsk).

Fix it, always access the objective credentials here.

I have tested that this bug can lead to a KASAN-reported UAF of struct cred
in smack_file_send_sigiotask(), and that this fix prevents the race.

Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
2026-08-08 09:47:22 -07:00
Linus Torvalds
c5096fec0c Merge tag 'selinux-pr-20260805' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux fixes from Paul Moore:

 - Continue to improve the validation of SELinux policies during load

 - Fix a SELinux regression caused by bpffs changes in v7.2-rc1

 - Fix a SELinux preformance regression caused by SELinux changes in
   v7.2-rc1

* tag 'selinux-pr-20260805' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: check level category sets once at load time
  selinux: require every boolean value to be defined
  selinux: reject an unclaimed class value in security_get_classes()
  selinux: require a class's permission values to cover its permission count
  selinux: do not cancel a policy conversion that never started
  selinux: bpf: check SBLABEL_MNT before isec init
  selinux: reject a class permission count below its inherited common
  selinux: reject a permission value exceeding the class permission count
2026-08-05 13:40:11 -07:00
Enrico Bravi
f1e10b1087 ima: measure userspace policy writes before parsing
When a signed policy is not mandatory, userspace can write IMA policy rules
directly to the securityfs policy file:

echo -e "measure func=BPRM_CHECK mask=MAY_EXEC\n" \
        "audit func=BPRM_CHECK mask=MAY_EXEC\n" \
     > /sys/kernel/security/ima/policy

or by cat'ing the entire IMA custom policy file:

cat ima-policy-file > /sys/kernel/security/ima/policy

Because these rules originate from userspace and cross the userspace/kernel
trust boundary, measure the raw write buffer before parsing, regardless of
whether the new policy will be accepted or not. This can be caught when
'measure func=POLICY_CHECK' is enabled (e.g., ima_policy=tcb). The
measurement template is forced to ima-buf.
This follows the "measure & load" paradigm, exposing potential bugs in
the policy code and detecting attempts to corrupt IMA. It also completes
the POLICY_CHECK hook, which already measures partial policy load by file.

To verify the template data hash value, convert the buffer policy data
to binary:
grep "ima_policy_written" \
	/sys/kernel/security/integrity/ima/ascii_runtime_measurements | \
	tail -1 | cut -d' ' -f 6 | xxd -r -p | sha256sum

Suggested-by: Roberto Sassu <roberto.sassu@huawei.com>
Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:03 -04:00
Enrico Bravi
f83a9cd965 ima: add critical data measurement for loaded policy
IMA policy can be written multiple times in the securityfs policy file
at runtime if CONFIG_IMA_WRITE_POLICY=y. When IMA_APPRAISE_POLICY is
required, the policy needs to be signed to be loaded, writing the absolute
path of the file containing the new policy:

echo /path/of/custom_ima_policy > /sys/kernel/security/ima/policy

When this is not required, policy can be written directly, rule by rule:

echo -e "measure func=BPRM_CHECK mask=MAY_EXEC\n" \
        "audit func=BPRM_CHECK mask=MAY_EXEC\n" \
     > /sys/kernel/security/ima/policy

In this case, a new policy can be loaded without being measured or
appraised.

Add a new critical data record to measure the textual policy
representation when it becomes effective. Include in the
architecture-specific policy the new critical data record only when it
is not mandatory to load a signed policy. Additionally, enable the
policy serialization code even when CONFIG_IMA_READ_POLICY=n.

To verify the template data hash value, convert the buffer policy data
to binary:
grep "ima_policy_loaded" \
        /sys/kernel/security/integrity/ima/ascii_runtime_measurements | \
        tail -1 | cut -d' ' -f 6 | xxd -r -p | sha256sum

Signed-off-by: Enrico Bravi <enrico.bravi@polito.it>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:03 -04:00
Mimi Zohar
b80bed5c87 ima: Instantiate file_truncate and path_truncate hooks
Instantiate the file_truncate and path_truncate LSM hooks to reset the
action cache flags (IMA_DONE_MASK) as soon as truncation is requested,
so the file, based on policy, is re-collected, re-measured, re-audited,
and re-appraised on next access.

Tested-by: Frederick Lawler <fred@cloudflare.com>
Cc: stable@vger.kernel.org
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:02 -04:00
Jonathan McDowell
c0fc127a98 security: ima: rename boot_aggregate when ima is initialised at late_sync
The Linux IMA (Integrity Measurement Architecture) subsystem used for
secure boot, file integrity, or remote attestation cannot be a loadable
module for few reasons listed below:

 o Boot-Time Integrity: IMA’s main role is to measure and appraise files
   before they are used. This includes measuring critical system files
   during early boot (e.g., init, init scripts, login binaries). If IMA
   were a module, it would be loaded too late to cover those.

 o TPM Dependency: IMA integrates tightly with the TPM to record
   measurements into PCRs. The TPM must be initialized early (ideally
   before init_ima()), which aligns with IMA being built-in.

 o Security Model: IMA is part of a Trusted Computing Base (TCB). Making
   it a module would weaken the security model, as a potentially
   compromised system could delay or tamper with its initialization.

IMA must be built-in to ensure it starts measuring from the earliest
possible point in boot which inturn implies TPM must be initialised and
ready to use before IMA.

Unfortunately some TPM drivers (such as Arm FF-A, or SPI attached TPM
devices) are not reliably available during the initcall_late stage,
resulting in a log error:

  ima: No TPM chip found, activating TPM-bypass!

To address this issue, IMA_INIT_LATE_SYNC is introduced.
However, a remote attestation service cannot determine when IMA has been
initialized because the boot_aggregate measurement name remains unchanged,
even though IMA is initialized later at late_initcall_sync when
IMA_INIT_LATE_SYNC is enabled.

Therefore, use a distinct boot_aggregate name when IMA_INIT_LATE_SYNC
is enabled, allowing the remote attestation service to identify
when IMA has been initialized.

Signed-off-by: Jonathan McDowell <noodles@meta.com>
[yeoreum.yun@arm.com: modified to align with the IMA_INIT_LATE_SYNC change]
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:02 -04:00
Lincoln Wallace
5ff232d311 ima: fix out-of-bounds read in xattr_verify()
The digest-length check in xattr_verify() mixes int and size_t:

	if (xattr_len - sizeof(xattr_value->type) - hash_start >=
			iint->ima_hash->length)

sizeof() yields size_t, so the usual arithmetic conversions promote
the whole left-hand side to unsigned 64-bit before the subtraction
runs. For a truncated xattr this underflows instead of going negative:
a 1-byte IMA_XATTR_DIGEST_NG xattr (xattr_len == 1, hash_start == 1)
turns "1 - 1 - 1" into SIZE_MAX, which is trivially >= ima_hash->length.
The check then passes and the following memcmp() reads
iint->ima_hash->length bytes starting past the end of the buffer
vfs_getxattr_alloc() allocated for it.

Nothing upstream clamps xattr_len back into a safe range first:
ima_get_hash_algo() only special-cases xattr_len < 2 to pick a default
algorithm, and evm_verifyxattr() returns INTEGRITY_UNKNOWN rather than
failing when no HMAC key is loaded, so a truncated security.ima value
reaches the length check as-is.

Rewrite the comparison so every operand stays a signed int and no
implicit conversion to size_t can occur.

Fixes: 3ea7a56067 ("ima: provide hash algo info in the xattr")
Cc: stable@vger.kernel.org
Signed-off-by: Lincoln Wallace <locnnil0@gmail.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:02 -04:00
Yeoreum Yun
1ebe7997b5 security: ima: introduce IMA_INIT_LATE_SYNC option
To generate the boot_aggregate log in the IMA subsystem with
TPM PCR values, the TPM driver must be built as built-in and
must be probed before the IMA subsystem is initialized.

However, when the TPM device operates over the FF-A protocol using
the CRB interface, probing fails and returns -EPROBE_DEFER if
the tpm_crb_ffa device — an FF-A device that provides the communication
interface to the tpm_crb driver — has not yet been probed.

To ensure the TPM device operating over the FF-A protocol with
the CRB interface is probed before IMA initialization,
the following conditions must be met:

1. The corresponding ffa_device must be registered,
   which is done via ffa_init().

2. The tpm_crb_driver must successfully probe this device via
   tpm_crb_ffa_init().

3. The tpm_crb driver using CRB over FF-A can then
   be probed successfully. (See crb_acpi_add() and
   tpm_crb_ffa_init() for reference.)

Unfortunately, ffa_init(), tpm_crb_ffa_init(), and crb_acpi_driver_init()
are all registered with device_initcall, which means
crb_acpi_driver_init() may be invoked before ffa_init() and
tpm_crb_ffa_init() are completed.

When this occurs, probing the TPM device is deferred.
However, the deferred probe can happen after the IMA subsystem
has already been initialized, since IMA initialization is performed
during late_initcall, and deferred_probe_initcall() is performed
at the same level.

And the similar situation is reported on TPM devices attached on SPI
bus[0].

To resolve this, introduce IMA_INIT_LATE_SYNC option to initialise
IMA at late_inicall_sync so that IMA is initialized with the TPM
device probed deferred.

When this option is enabled, modules that access files in the
initramfs through usermode helper calls such as request_module()
during initcall must not be built-in. Otherwise, IMA may miss
measuring those files [1].

Link: https://lore.kernel.org/all/aYXEepLhUouN5f99@earth.li/ [0]
Link: https://lore.kernel.org/all/2b3782398cc17ce9d355490a0c42ebce9120a9ae.camel@linux.ibm.com/ [1]
Suggested-by: Mimi Zohar <zohar@linux.ibm.com>
Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
[zohar@linux.ibm.com: Fixed Kconfig merge conflict]
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:02 -04:00
Yeoreum Yun
fd88b5cb8b security: lsm: allow LSMs to register for late_initcall_sync init
There are situations where LSMs have dependencies that might mean they
want to be initialised later in the boot process, to ensure those
dependencies are available. In particular there are some TPM setups (Arm
FF-A devices, SPI attached TPMs) required by IMA which are not
guaranteed to be initialised for regular initcall_late.

Add an initcall_late_sync option that can be used in these situations.

Signed-off-by: Yeoreum Yun <yeoreum.yun@arm.com>
Cc: Paul Moore <paul@paul-moore.com>
Acked-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Mimi Zohar <zohar@linux.ibm.com>
2026-08-04 12:35:02 -04:00
Stephen Smalley
9c1cc4a7f7 selinux: check level category sets once at load time
As reported by Jiri Vozar, commit 7edea6e8c8 ("selinux: beef up
isvalid checks") introduces a new loop in mls_level_isvalid() that
causes ~89-94% throughput regression in System V IPC message queue
operations (msgsnd/msgrcv).

Move the expensive part of the ebitmap checking to policy load time
instead as the reporter suggested.

Link: https://lore.kernel.org/selinux/CAMgFczCi2Z011dNf84Amc0Q-qnTt0+VUjWY+Y7zPyXdaH35Jvw@mail.gmail.com/
Fixes: 7edea6e8c8 ("selinux: beef up isvalid checks")
Reported-by: Jiri Vozar <jvozar@redhat.com>
Suggested-by: Jiri Vozar <jvozar@redhat.com>
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-08-04 10:57:46 -04:00
Bryam Vargas
a93d37a09b selinux: require every boolean value to be defined
p_bools.nprim comes from the policy image independently of how many
booleans follow it, and cond_index_bool() fills bool_val_to_struct[] at
value - 1, so a count larger than the values present leaves NULL entries.
Every user of that array then walks it by index and dereferences each
entry: cond_evaluate_expr() on the access-vector path,
security_get_bools() and security_get_bool_value() behind selinuxfs, and
security_set_bools(). A sparse class value is absorbed by
policydb_class_isvalid() and its siblings; booleans have no such
predicate, and no consumer that could use one.

Reject a boolean value that no boolean defines, once, where the array is
built. Conforming policies define every boolean they declare and are
unaffected.

Cc: stable@vger.kernel.org
Fixes: 1da177e4c3 ("Linux-2.6.12-rc2")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-08-03 16:03:57 -04:00
Bryam Vargas
22b05fec62 selinux: reject an unclaimed class value in security_get_classes()
security_get_classes() sizes an array by p_classes.nprim and fills it at
value - 1, so a class value the policy never defines leaves a NULL.
sel_make_classes() passes every entry to sel_make_dir(), reaching the same
d_alloc_name() dereference as the permission array. The class symbol table
is allowed to be sparse (policydb_class_isvalid() exists to absorb that),
but this getter builds its own array straight from the hash table and has
no such predicate.

Fail the lookup when a value went unclaimed instead of handing out the
NULL. Conforming policies define every class they declare and are
unaffected.

Cc: stable@vger.kernel.org
Fixes: 55fcf09b3f ("selinux: add support for querying object classes and permissions from the running policy")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-08-03 16:03:56 -04:00
Bryam Vargas
b98a8ac507 selinux: require a class's permission values to cover its permission count
security_get_permissions() sizes an array by the class's permissions.nprim
and fills it at value - 1, from the inherited common's permission table and
then the class's own. A value no permission defines leaves a NULL that
sel_make_perm_files() passes to d_alloc_name(), an oops inside
sel_write_load() that strands selinux_state.policy_mutex and leaves every
later load in uninterruptible sleep; two permissions sharing a value
overwrite the first kstrdup(). Bounding each value by nprim catches
neither, and neither would a count: the symbol table is keyed on the
permission name, so duplicates pass.

Track the values each permission table claims and require them to cover
exactly what its count declares, rejecting a count no value can reach.
Conforming policies are unaffected.

Cc: stable@vger.kernel.org
Fixes: 55fcf09b3f ("selinux: add support for querying object classes and permissions from the running policy")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-08-03 16:03:56 -04:00
Bryam Vargas
e5c0235a3c selinux: do not cancel a policy conversion that never started
sel_write_load() calls selinux_policy_cancel() when sel_make_policy_nodes()
fails, and that helper dereferences the outgoing policy to cancel its
sidtab conversion. On the first policy load there is no outgoing policy:
security_load_policy() returns early for that case, before it converts
anything, and state->policy is still NULL. A first load that fails while
building the selinuxfs tree therefore takes a NULL dereference in
selinux_policy_cancel(), reached from a write(2) to /sys/fs/selinux/load.

Skip the cancel when there is no old policy, mirroring the check
security_load_policy() already makes before it converts.

Cc: stable@vger.kernel.org
Fixes: 02a52c5c8c ("selinux: move policy commit after updating selinuxfs")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-08-03 16:03:55 -04:00
Carlos Llamas
28254722a4 selinux: bpf: check SBLABEL_MNT before isec init
selinux_inode_init_security() marks the isec as initialized before
checking if mount labeling is supported (SBLABEL_MNT). This was fine
until commit 9722955b54 ("bpf: Add simple xattr support to bpffs"),
where genfscon bpffs mounts fail the SBLABEL_MNT check as expected (no
xattrs) and yet leave the isec->initialized. This breaks subsequent
calls to inode_doinit_with_dentry().

Do the SBLABEL_MNT check before the inode security is initialized.

Cc: stable@vger.kernel.org
Closes: https://lore.kernel.org/all/akWdcp6P0FkNDzBk@google.com/
Fixes: 9722955b54 ("bpf: Add simple xattr support to bpffs")
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Carlos Llamas <cmllamas@google.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-31 11:33:53 -04:00
Bryam Vargas
9a82dcd98b selinux: reject a class permission count below its inherited common
security_get_permissions() maps an inherited common's permissions into
an array sized by the class's own permissions.nprim, but class_read()
takes that nprim verbatim from the policy image and never checks that it
covers the common.  A class that inherits a common of N permissions while
declaring a smaller nprim is accepted, and on load the common's
permissions are written past the class-sized array -- an out-of-bounds
heap write.

Reject a class whose permission count is below its inherited common's.
Well-formed policies, where the class count already includes the
inherited permissions, are unaffected.

Cc: stable@vger.kernel.org
Fixes: 55fcf09b3f ("selinux: add support for querying object classes and permissions from the running policy")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-30 16:14:50 -04:00
Bryam Vargas
d14b5d0e97 selinux: reject a permission value exceeding the class permission count
perm_read() bounds a permission value by SEL_VEC_MAX but never by the
nprim of the owning class or common, which is taken verbatim from the
policy image.  security_get_permissions() then writes perms[value - 1]
into an nprim-sized kcalloc() array, so a class declaring fewer
permissions than its largest permission value drives an out-of-bounds
heap write.  The top-level symbol tables are validated this way; the
nested per-class permission table is not.

Reject a permission whose value exceeds nprim, which is already set when
perm_read() runs.  Well-formed policies are unaffected.

Cc: stable@vger.kernel.org
Fixes: 55fcf09b3f ("selinux: add support for querying object classes and permissions from the running policy")
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: tweak comment for line length]
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-30 16:14:50 -04:00
Stephen Smalley
fd6e2388a3 selinux: validate constraint expression attr and op at load time
read_cons_helper() validates the expression type and stack depth
of each constraint node but leaves e->attr and e->op unchecked,
so a policy with an invalid operator or attribute value is
accepted at load and only detected when the constraint is evaluated.
constraint_expr_eval() handles such unrecognized cases with BUG()
so the first permission check that reaches such a node oopses in
the context of the checking process or panics with panic_on_oops.

Reject these expresssions when the policy is loaded, matching what
the libsepol validator already does.

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-27 17:17:33 -04:00
Michael Bommarito
58565eef0f keys: make keyring key-chunk byte order agree with keyring_diff_objects()
keyring_get_key_chunk() loads description bytes into the index chunk low
address first, while keyring_diff_objects() numbers the first differing
bit from the low end and folds the absolute byte index into the level
without removing the inline-prefix offset the level already carries.
The two disagree on byte order and bit position, so the array can be
told two keys first differ at a bit that does not differ in the chunk
the walker uses, letting crafted descriptions collide into one node.

Load the chunk in the order keyring_diff_objects() assumes and drop the
inline-prefix length when folding the byte index into the level.  This
only changes the in-memory ordering used to place keys within a keyring;
add, search and read of non-colliding keys are unaffected.

Fixes: f771fde820 ("keys: Simplify key description management")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260719161505.2423935-3-michael.bommarito@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-07-23 18:23:39 +03:00
Michael Bommarito
63918731f9 keys: fix out-of-bounds read in keyring_get_key_chunk()
For description-level chunks keyring_get_key_chunk() advances the read
pointer by level * sizeof(long) past the inline prefix but only
bounds-checks the prefix, so a long enough key description is read past
its kmemdup(desc, desc_len + 1) allocation.  Compute the full byte
offset and bounds-check the description against it before reading.

The walk only reaches a description-level chunk when two keys collide
through the hash, x, type and domain_tag chunks, so this is reached from
an unprivileged add_key(2) with a crafted pair of same-type keys whose
index hashes collide; KASAN reports a slab-out-of-bounds read.

Fixes: f771fde820 ("keys: Simplify key description management")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260719161505.2423935-2-michael.bommarito@gmail.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-07-23 18:23:32 +03:00
Fabrice Derepas
35d661c98f KEYS: trusted: dcp: fix key_len validation and calc_blob_len() return type
Two correctness and type-hygiene issues exist in the DCP trusted keys
implementation.

First, trusted_dcp_unseal() reads p->key_len from a user-supplied blob
without checking if it exceeds MAX_KEY_SIZE.  If a crafted blob provides a
payload_len larger than 128, the subsequent do_aead_crypto() call writes
past the end of the p->key array into the adjacent p->blob buffer within
the same struct trusted_key_payload -- the caller's own input, not
unrelated kernel memory.  While not exploitable, this violates strict array
bounds and triggers static analyzers.  Fix this by adding a validation
check against MIN_KEY_SIZE and MAX_KEY_SIZE immediately after reading the
length, matching the checks already done in trusted_core.c.

Second, calc_blob_len() calculates a sum in size_t that truncates to
unsigned int on 64-bit platforms.  Because the DCP hardware is only present
on 32-bit i.MX SoC platforms, size_t and unsigned int are functionally
equivalent in production, making this truncation harmless in practice.
Nevertheless, updating the return type to size_t (and subsequently updating
'blen' in the seal/unseal paths) resolves type-narrowing warnings and
improves overall code hygiene.

Fixes: 2e8a0f40a3 ("KEYS: trusted: Introduce NXP DCP-backed trusted keys")
Signed-off-by: Fabrice Derepas <fabrice.derepas@canonical.com>
Reviewed-by: David Gstir <david@sigma-star.at>
Reviewed-by: Richard Weinberger <richard@nod.at>
Reviewed-by: Jarkko Sakkinen <jarkko@kernel.org>
Tested-by: Jarkko Sakkinen <jarkko@kernel.org>
Link: https://lore.kernel.org/r/20260719163939.3624767-1-fabrice.derepas@canonical.com
Signed-off-by: Jarkko Sakkinen <jarkko@kernel.org>
2026-07-23 18:23:23 +03:00
Linus Torvalds
8fc574321e Merge tag 'selinux-pr-20260717' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux fix from Paul Moore:
 "A single SELinux patch to correct a problem with the overlayfs mmap()
  and mprotect() fixes from earlier this year where we inadvertenly
  included an additional SELinux execmem permission check on some
  operations"

* tag 'selinux-pr-20260717' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: fix incorrect execmem checks on overlayfs
2026-07-17 11:04:46 -07:00
Linus Torvalds
481ed5dd3e Merge tag 'landlock-7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux
Pull landlock fix from Mickaël Salaün:
 "This fixes TCP Fast Open support, specific test environments, and doc
  warnings"

* tag 'landlock-7.2-rc4' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
  selftests/landlock: Skip scoped_signal subtest with MSG_OOB if not available
  selftests/landlock: Fix screwed up pointers in the scoped_signal_test
  landlock: Update formatting
  landlock: Fix kernel-doc for the nested quiet layer flag
  selftests/landlock: Add test for TCP fast open
  landlock: Fix TCP Fast Open connection bypass
2026-07-16 13:22:17 -07:00
Ian Bridges
c0b6a5b89d selinux: compute the IMA configuration settings string length once at boot
selinux_ima_collect_state() builds a string of the current SELinux
configuration settings. The string lists each setting as a name and
one digit. The length of the string therefore never changes, but is
still recomputed on every call.

Add selinux_ima_config_len_init() to compute the length once during
selinux_init(). Update selinux_ima_collect_state() to use the stored
length.

Suggested-by: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/df755e0282dab3b932d19aceab71b7d7@paul-moore.com
Signed-off-by: Ian Bridges <icb@fastmail.org>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-15 21:42:01 -04:00
Ondrej Mosnacek
9fe595fad5 selinux: fix incorrect execmem checks on overlayfs
The commit fixing the overlayfs mmap() and mprotect() access checks
failed to skip the execmem check in __file_map_prot_check() for the case
where the "mounter check" is being performed. This check should be
performed only against the credentials of the task that is calling
mmap()/mprotect(), since it doesn't pertain to the file itself, but
rather just gates the ability of the calling task to get an executable
memory mapping in general.

The purpose of the "mounter check" is to guard against using an
overlayfs mount to gain file access that would otherwise be denied to
the mounter. For execmem this is not relevant, as there is no further
file access granted based on it (notice that the file's context is not
used as the target in the check), so checking it also against the
mounter credentials would be incorrect.

Fix this by passing a boolean to [__]file_map_prot_check() and
selinux_mmap_file_common() that indicates if we are doing the "mounter
check" and skiping the execmem check in that case. Since this boolean
also indicates if we use current_cred() or the mounter cred as the
subject, also remove the "cred" argument from these functions and
determine it based on the boolean and the file struct.

Cc: stable@vger.kernel.org
Fixes: 82544d36b1 ("selinux: fix overlayfs mmap() and mprotect() access checks")
Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-14 18:10:20 -04:00
Ian Bridges
00f73e2a48 selinux: replace strlcat() with seq_buf in selinux_ima_collect_state()
In preparation for removing the deprecated strlcat() API[1], replace the
strscpy()/strlcat() chain in selinux_ima_collect_state() with a struct
seq_buf, which tracks the write position and remaining space internally.

Each field is written with seq_buf_printf() using a "=%d;" format, which
removes the open-coded "=1;"/"=0;" constants. The seven per-append
WARN_ON(rc >= buf_len) truncation checks are replaced by a single
seq_buf_has_overflowed() check after the string is built.

Link: https://github.com/KSPP/linux/issues/370 [1]
Signed-off-by: Ian Bridges <icb@fastmail.org>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-13 18:15:30 -04:00
Yafang Shao
e7a614c008 selinux: suppress warning flood for retired DCCP netlink messages
When deploying linux-6.18.y stable kernel to production servers, we
observed kernel dmesg being flooded with SELinux warnings when running
`ss -l`:

  SELinux: unrecognized netlink message: protocol=4 nlmsg_type=19 \
    sclass=netlink_tcpdiag_socket pid=188945 comm=ss

The root cause is that DCCP support was retired in
commit 2a63dd0edf ("net: Retire DCCP socket."). Consequently,
DCCPDIAG_GETSOCK was removed from nlmsg_tcpdiag_perms. This causes
nlmsg_perm() to return -EINVAL, triggering the SELinux warning for every
`ss -l` invocation [0].

Use pr_warn_once() for the retired DCCPDIAG_GETSOCK to prevent message
flooding.

Link: https://github.com/iproute2/iproute2/blob/main/misc/ss.c#L3901 [0]
Fixes: 2a63dd0edf ("net: Retire DCCP socket.")
Suggested-by: Paul Moore <paul@paul-moore.com>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Cc: Kuniyuki Iwashima <kuniyu@google.com>
Cc: Stephen Smalley <stephen.smalley.work@gmail.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-13 17:26:17 -04:00
Linus Torvalds
ccce5f6e7c Merge tag 'selinux-pr-20260710' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux
Pull selinux fixes from Paul Moore:
 "Two small SELinux patches to fix a missing permission check for TCP
  Fast Open operations and fix a socket lookup issue with SCTP ASCONF
  operations"

* tag 'selinux-pr-20260710' of git://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux:
  selinux: avoid sk_socket dereference in selinux_sctp_bind_connect()
  selinux: check connect-related permissions on TCP Fast Open
2026-07-10 18:59:29 -07:00
Mickaël Salaün
97c0e344e0 landlock: Update formatting
Following commit 99df2a8eba ("clang-format: fix formatting of guard()
and scoped_guard() statements"), update scoped_guard() formatting.
Also, see the related fix [1].

Cc: Günther Noack <gnoack@google.com>
Cc: Miguel Ojeda <ojeda@kernel.org>
Link: https://lore.kernel.org/r/20260708105713.2073335-1-mic@digikod.net [1]
Link: https://patch.msgid.link/20260708110635.2083515-1-mic@digikod.net
Reviewed-by: Günther Noack <gnoack@google.com>
Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-07-10 12:59:10 +02:00
Mickaël Salaün
592a37889f landlock: Fix kernel-doc for the nested quiet layer flag
kernel-doc emits "Excess struct member 'quiet' description in
'landlock_layer'" because "quiet" is a bitfield inside the named nested
struct "flags", but its inline comment used the bare member name
"@quiet:", which kernel-doc attributes to the enclosing landlock_layer.

Use the canonical dotted notation "@flags.quiet:" so kernel-doc resolves
the nested member, and include it in the generated documentation.

Cc: Justin Suess <utilityemal77@gmail.com>
Cc: Tingmao Wang <m@maowtm.org>
Fixes: a260c00556 ("landlock: Add a place for flags to layer rules")
Link: https://patch.msgid.link/20260703141711.2016964-1-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-07-10 12:59:09 +02:00
Matthieu Buffet
33cb713db0 landlock: Fix TCP Fast Open connection bypass
The documentation of the socket_connect() LSM hook states that it
controls connecting a socket to a remote address. It has not been the
case since the addition of TCP Fast Open (RFC 7413) support, which
allows opening a TCP connection (thus, setting a socket's destination
address) via the MSG_FASTOPEN flag passed to
sendto()/sendmsg()/sendmmsg(). The problem then got duplicated into
MPTCP.

Landlock did not take it into account when its TCP support was added,
leaving a bypass of TCP connect policy.

Ideally a call to the LSM hook would be added in the fastopen code path,
in order to fix this generically. But connect() hooks are designed to
run with the socket locked, unlike sendmsg() hooks.

Closes: https://github.com/landlock-lsm/linux/issues/41
Fixes: fff69fb03d ("landlock: Support network rules with TCP bind and connect")
Signed-off-by: Matthieu Buffet <matthieu@buffet.re>
Link: https://patch.msgid.link/20260701214628.33319-1-matthieu@buffet.re
Cc: stable@vger.kernel.org
[mic: Wrap commit message]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
2026-07-10 12:59:07 +02:00
Bill Roberts
149b192e37 lsm: clarify security_task_prctl() hook documentation
The task_prctl hook comment incorrectly described the hook as checking
whether a prctl operation is allowed. In reality, the hook exists for
LSMs to handle LSM-specific prctl operations.

Update the function description and kernel-doc comment to reflect the
actual behavior. The old wording appears to have been copied from other
permission-check hooks despite differing semantics.

Signed-off-by: Bill Roberts <bill.roberts@arm.com>
Acked-by: Casey Schaufler <casey@schaufler-ca.com>
Reviewed-by: Serge Hallyn <serge@hallyn.com>
[PM: subj tweak, comment tweak -> "prctl to prctl()" ]
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-02 14:59:24 -04:00
Stephen Smalley
ef0740b4b7 selinux: tighten type validation during policy load
Tighten type validation during policy load to improve robustness in
the face of ill-formed policies.

Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-02 12:36:15 -04:00
Tristan Madani
56acfeb100 selinux: avoid sk_socket dereference in selinux_sctp_bind_connect()
selinux_sctp_bind_connect() dereferences sk->sk_socket to pass a
struct socket * to selinux_socket_bind() and
selinux_socket_connect_helper().  However, when the hook is invoked
from the ASCONF softirq path (sctp_process_asconf), there is no file
reference guaranteeing that sk->sk_socket is non-NULL.  The setsockopt
callers (bindx, connectx, set_primary, sendmsg connect) hold a file
reference and are not affected.

Both selinux_socket_bind() and selinux_socket_connect_helper()
immediately resolve sock->sk, never using the struct socket * for
anything else.  Refactor the inner logic into helpers that take a
struct sock * directly so that selinux_sctp_bind_connect() never needs
to touch sk->sk_socket at all.

Cc: stable@vger.kernel.org
Fixes: d452930fd3 ("selinux: Add SCTP support")
Suggested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Reviewed-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Tested-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-01 18:22:22 -04:00
Kalevi Kolttonen
d3e4784c2b selinux: drop unnecessary goto and label from avc_alloc_node()
Since avc_alloc_node() doesn't need to perform any cleanup on
its exit paths, there is no benefit to keeping the out
label and goto statement. Drop it.

Signed-off-by: Kalevi Kolttonen <kalevi@kolttonen.fi>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-01 17:42:19 -04:00
Kalevi Kolttonen
64740a0588 selinux: convert int flags to bool flags in ss/services.c
Update security_sid_to_context_core(), security_context_to_sid_core(),
and their callers to pass boolean flags via bool rather than int.
No functional change.

Signed-off-by: Kalevi Kolttonen <kalevi@kolttonen.fi>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
[PM: minor subject and description tweaks]
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-01 17:40:52 -04:00
Haoxiang Li
dc67c654bc selinux: clean up selinuxfs resources on init failure
init_sel_fs() creates the selinuxfs mount point and registers the
filesystem before mounting selinuxfs internally. If kern_mount()
or the subsequent lookup of the null file fails, the function
returns without undoing the resources that were already registered.

Add the missing error unwinding so the internal mount, filesystem
registration, and sysfs mount point are released as appropriate.

Signed-off-by: Haoxiang Li <haoxiang_li2024@163.com>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-01 17:17:41 -04:00
Stephen Smalley
44c74d27d1 selinux: check connect-related permissions on TCP Fast Open
Similar to Landlock, SELinux was not updated when TCP Fast Open
support was introduced to ensure connect-related permissions are
checked when using TCP Fast Open. Update its socket_sendmsg() hook to
call selinux_socket_connect() when MSG_FASTOPEN is passed.

Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/linux-security-module/20260616201615.275032-1-hexlabsecurity@proton.me/
Link: https://lore.kernel.org/linux-security-module/20260617180526.15627-2-matthieu@buffet.re/
Reported-by: Bryam Vargas <hexlabsecurity@proton.me>
Reported-by: Matthieu Buffet <matthieu@buffet.re>
Reported-by: Mikhail Ivanov <ivanov.mikhail1@huawei-partners.com>
Signed-off-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Tested-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-07-01 17:09:53 -04:00
Mike Rapoport (Microsoft)
5adb9195e0 selinux: hooks: use kmalloc() to allocate path buffer
selinux_genfs_get_sid() allocates memory for a path with __get_free_page().

Such usage does not require a "page" and the size of the buffer should
actually be PATH_MAX which may be less than PAGE_SIZE on some
architectures.

Replace __get_free_page() for allocation of a path buffer with kmalloc()
and make it explicit that the buffer size is PATH_MAX.

Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
2026-06-30 20:58:07 -04:00
Matt Bobrowski
a6f0643e4f bpf: Reject BPF_MAP_TYPE_INODE_STORAGE creation if BPF LSM is uninitialized
When CONFIG_BPF_LSM=y is set, BPF inode storage maps
(BPF_MAP_TYPE_INODE_STORAGE) are compiled into the kernel. However,
if the BPF LSM is not explicitly enabled at boot time (e.g. omitted
from the "lsm=" boot parameter), lsm_prepare() is never executed for
the BPF LSM.

Consequently, the BPF inode security blob offset
(bpf_lsm_blob_sizes.lbs_inode) is never initialized and remains at
its default compiled size of 8 bytes instead of being updated to a
valid offset past the reserved struct rcu_head (typically 16 bytes
or more).

When a privileged user creates and updates a BPF_MAP_TYPE_INODE_STORAGE
map, bpf_inode() evaluates inode->i_security + 8. This erroneously
aliases the struct rcu_head.func callback pointer at the beginning
of the inode->i_security blob. During subsequent map element cleanup
or inode destruction, writing NULL to owner_storage clears the queued
RCU callback pointer. When rcu_do_batch() later executes the queued
callback, it attempts an instruction fetch at address 0x0, triggering
an immediate kernel panic.

Fix this by introducing a global bpf_lsm_initialized boolean flag
marked with __ro_after_init. Set this flag to true inside bpf_lsm_init()
when the LSM framework successfully registers the BPF LSM. Gate map
allocation in inode_storage_map_alloc() on this flag, returning
-EOPNOTSUPP if the BPF LSM is in turn uninitialized.

This fail-fast approach prevents userspace from allocating inode
storage maps when the supporting BPF LSM infrastructure is absent,
avoiding zombie map states.

Fixes: 8ea636848a ("bpf: Implement bpf_local_storage for inodes")
Reported-by: oxsignal <awo@kakao.com>
Signed-off-by: Matt Bobrowski <mattbobrowski@google.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Reviewed-by: Amery Hung <ameryhung@gmail.com>
Link: https://lore.kernel.org/bpf/20260628201103.3624525-1-mattbobrowski@google.com
2026-06-30 16:31:56 +02:00
Linus Torvalds
6535a84bfd Merge tag 'apparmor-pr-2026-06-22' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor
Pull apparmor updates from John Johansen:
 "Another round of bug fixing and some code cleanups, there are no new
  features. The biggest thing to note is Georgia is being added to help
  co-maintain apparmor.

  Cleanups:
   - replace get_zeroed_page() with kzalloc()
   - remove unnecessary goto and associated label
   - change fn_label_build() to return err on failure instead of NULL or
     err
   - free rawdata as soon as possible
   - use explicit instead of implicit flex array in rawdata_f_data
   - use __label_make_stale in __aa_proxy_redirect
   - return correct error by propagate -ENOMEM correctly in unpack_table
   - aa_label_alloc use aa_label_free on alloc failure
   - add a conditional version of get_newest_label

  Bug Fixes:
   - mediate the implicit connect of TCP fast open sendmsg
   - fix C23ism of label immediately before a declaration
   - fix kernel-doc warnings
   - fix spelling mistakes
   - fix use-after-free in rawdata dedup loop
   - Fix inverted comparison in cache_hold_inc()
   - fix uninitialized pointer passed to audit_log_untrustedstring()
   - don't audit files pointing to aa_null.dentry
   - put secmark label after secid lookup
   - fix aa_getprocattr free procattr leak on format failure
   - release exe file resources on path failure
   - fail policy unpack on accept2 allocation failure
   - Fix return in ns_mkdir_op
   - remove or add symlinks to rawdata according to export_binary
   - fix NULL pointer dereference in unpack_pdb
   - fix potential UAF in aa_replace_profiles
   - grab ns lock and refresh when looking up changehat child profiles
   - enable differential encoding
   - check label build before no_new_privs test
   - conditionally compile get_loaddata_common_ref()
   - fix unix socket mediation cache update, and leak"

* tag 'apparmor-pr-2026-06-22' of git://git.kernel.org/pub/scm/linux/kernel/git/jj/linux-apparmor: (35 commits)
  apparmor: advertise the tcp fast open fix is applied
  apparmor: mediate the implicit connect of TCP fast open sendmsg
  apparmor: fix label can not be immediately before a declaration
  apparmor: fix kernel-doc warnings
  apparmor: replace get_zeroed_page() with kzalloc()
  security: apparmor: fix two spelling mistakes
  apparmor: fix use-after-free in rawdata dedup loop
  apparmor: Fix inverted comparison in cache_hold_inc()
  apparmor: fix uninitialised pointer passed to audit_log_untrustedstring()
  apparmor: don't audit files pointing to aa_null.dentry
  apparmor: put secmark label after secid lookup
  apparmor: aa_getprocattr free procattr leak on format failure
  apparmor: remove unnecessary goto and associated label
  apparmor: release exe file resources on path failure
  apparmor: fail policy unpack on accept2 allocation failure
  apparmor: Fix return in ns_mkdir_op
  apparmor: remove or add symlinks to rawdata according to export_binary
  apparmor: fix NULL pointer dereference in unpack_pdb
  apparmor: make fn_label_build() capable of handling not supported
  apparmor: change fn_label_build() call to not return NULL
  ...
2026-06-24 12:33:40 -07:00
John Johansen
2f6701a5ce apparmor: advertise the tcp fast open fix is applied
The fix for tcp-fast-open ensures that the connect permission is being
mediated correctly but it didn't add an artifact to the feature set to
advertise the fix is available. Add an artifact so that the test suite
can identify if the fix has not been properly applied or a new
unexpected regression has occurred.

Fixes: 4d587cd8a7 ("apparmor: mediate the implicit connect of TCP fast open sendmsg")
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-06-23 22:15:15 -07:00
Bryam Vargas
4d587cd8a7 apparmor: mediate the implicit connect of TCP fast open sendmsg
sendmsg()/sendto() with MSG_FASTOPEN is a combination of connect(2) and
write(2): it opens the connection in the SYN. apparmor_socket_sendmsg()
only checks AA_MAY_SEND, so a profile that grants send but denies connect
lets a confined task open an outbound TCP/MPTCP connection that connect(2)
would have refused, bypassing connect mediation.

Mediate the implicit connect when MSG_FASTOPEN is set and a destination
is supplied. Add it to apparmor_socket_sendmsg() (not the shared
aa_sock_msg_perm() helper, which recvmsg also uses) and call aa_sk_perm()
directly, mirroring the selinux and tomoyo fixes. sk_is_tcp() does not
cover MPTCP fast open, so the SOCK_STREAM/IPPROTO_MPTCP arm is explicit.

Fixes: cf60af03ca ("net-tcp: Fast Open client - sendmsg(MSG_FASTOPEN)")
Cc: stable@vger.kernel.org
Signed-off-by: Bryam Vargas <hexlabsecurity@proton.me>
Signed-off-by: John Johansen <john.johansen@canonical.com>
2026-06-23 00:16:59 -07:00
Konstantin Andreev
a7c44fd9f8 smack: restrict smackfs/{direct,mapped} values to 0-255
Both smackfs/direct and smackfs/mapped incorrectly accept
the full range of integer values. For example:

    # cd /sys/fs/smackfs/
    # cat direct ; echo
    250

    # cat cipso2
    @ 250/2
    _ 250/2,4,5,6,7,8
    * 250/3,5,7
    ^ 250/2,4,5,6,7
    ? 250/3,4,5,6,7,8

    # echo -1234 >direct ; cat direct ; echo
    -1234
    # cat cipso2
    @ -1234/2
    _ -1234/2,4,5,6,7,8
    * -1234/3,5,7
    ^ -1234/2,4,5,6,7
    ? -1234/3,4,5,6,7,8
    #

I noticed two things regarding this:

1) sensitivity levels are truncated to 8 bits when labeling
   outgoing packets (0x2e = 46 for the -1234 example above)

2) the reverse process fails: incoming packets with sensitivity
   level 46 do not match these smackfs/cipso2 entries.

Even observation (1) on its own warrants a fix.

This patch restricts smackfs/direct and smackfs/mapped
accepted values to the 0-255 range.

Fixes: e114e47377 ("Smack: Simplified Mandatory Access Control Kernel")
Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
2026-06-22 13:52:24 -07:00
Konstantin Andreev
577dc3b6a8 smack: deduplicate smackfs/{direct,mapped} file_operations
The file_operations for smackfs/direct and smackfs/mapped are
identical up to a textual replacement of "direct" with "mapped"

This patch combines two instances of file_operations into one,
handling both files.

Fixes: f7112e6c9a ("Smack: allow for significantly longer Smack labels v4")
Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
2026-06-22 13:52:07 -07:00
Konstantin Andreev
0bcb3c5e71 smack: show msgrcv() subject task in audit
When a task msgrcv()'es some message the SMACK audit log message
looks like:

  fn=smk_tskacc_msq action=denied subject="bar" object="foo" requested=rw
	pid=456 comm="mrcv" ipc_key=2
  fn=smk_tskacc_msq action=granted subject="bar" object="foo" requested=rw
	pid=519 comm="mrcv" ipc_key=2

where pid= is a pid of a “current” task which calls smk_tskacc_msq().
Usually, the caller of smk_tskacc_msq() is also a subject task
which determines its own permission. In the example above
the 'mrcv' process has label 'bar' and wants "rw" for label "foo".

However, when sender task delivers message using

  ipc/msg.c`pipelined_send():
  ` security_msg_queue_msgrcv(,, msr->r_tsk,,)
  ` smp_store_release(&msr->r_msg, msg)

“current” task and “subject” task differ, and
the “subject” task is missed from the audit message.

This patch adds two fields, subj_pid and subj_comm,
into the audit message:

  fn=smk_tskacc_msq action=granted subject="bar" object="foo" requested=rw
	subj_pid=564 subj_comm="mrcv" pid=577 comm="msnd" ipc_key=2

Signed-off-by: Konstantin Andreev <andreev@swemel.ru>
Signed-off-by: Casey Schaufler <casey@schaufler-ca.com>
2026-06-22 11:16:40 -07:00