<feed xmlns='http://www.w3.org/2005/Atom'>
<title>linux-stable.git/security/apparmor, branch v6.18.50</title>
<subtitle>Linux kernel stable tree</subtitle>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/'/>
<entry>
<title>apparmor: fix out-of-bounds write when null terminating a label vec</title>
<updated>2026-09-07T15:22:21+00:00</updated>
<author>
<name>Hyunwoo Kim</name>
<email>imv4bel@gmail.com</email>
</author>
<published>2026-08-10T09:51:33+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=28069434aef66b9d084f0609b7a29c171846815e'/>
<id>28069434aef66b9d084f0609b7a29c171846815e</id>
<content type='text'>
commit 9f1e40193eef7f047e6b77cfb4b4cafdecd7a123 upstream.

aa_vec_unique() null terminates at vec[n - dups] when VEC_FLAG_TERMINATE
is passed. If the components are all distinct no duplicates are dropped,
dups is 0 and the terminator goes to vec[n], so the caller has to provide
room for n + 1 entries.

aa_label_strn_parse() sets up its vector with vec_setup(profile, vec, len,
gfp) and then calls aa_vec_unique(vec, len, VEC_FLAG_TERMINATE), but
vec_setup() does not reserve the terminator entry. Up to LOCAL_VEC_ENTRIES
it uses the local array of LOCAL_VEC_ENTRIES pointers, above that it
allocates exactly len pointers. The terminator therefore lands one entry
past the end of the local array when len is LOCAL_VEC_ENTRIES, and one
entry past the end of the allocation when len is larger.

len comes from the number of "//&amp;" separated components in the label name
and label_count_strn_entries() does not bound it. An unprivileged task
reaches the parse by writing to /proc/self/attr/apparmor/current or through
lsm_set_self_attr(2), both of which go through do_setattr(), and the name
is parsed before the change_profile permission is checked.
The query_label() path behind the securityfs .access file, which is
mode 0666, performs no permission check at all. Every component has to
resolve to a loaded profile, so a system with policy loaded is required.

The other two VEC_FLAG_TERMINATE users work on a label vec that
aa_label_alloc() has already sized with "+ 1 for null terminator entry on
vec". Reserve the same entry in vec_setup() and DEFINE_VEC(). Passing
len + 1 from the caller instead would move len == LOCAL_VEC_ENTRIES out of
the local array and into kzalloc().

Fixes: f1bd904175e8 ("apparmor: add the base fns() for domain labels")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim &lt;imv4bel@gmail.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 9f1e40193eef7f047e6b77cfb4b4cafdecd7a123 upstream.

aa_vec_unique() null terminates at vec[n - dups] when VEC_FLAG_TERMINATE
is passed. If the components are all distinct no duplicates are dropped,
dups is 0 and the terminator goes to vec[n], so the caller has to provide
room for n + 1 entries.

aa_label_strn_parse() sets up its vector with vec_setup(profile, vec, len,
gfp) and then calls aa_vec_unique(vec, len, VEC_FLAG_TERMINATE), but
vec_setup() does not reserve the terminator entry. Up to LOCAL_VEC_ENTRIES
it uses the local array of LOCAL_VEC_ENTRIES pointers, above that it
allocates exactly len pointers. The terminator therefore lands one entry
past the end of the local array when len is LOCAL_VEC_ENTRIES, and one
entry past the end of the allocation when len is larger.

len comes from the number of "//&amp;" separated components in the label name
and label_count_strn_entries() does not bound it. An unprivileged task
reaches the parse by writing to /proc/self/attr/apparmor/current or through
lsm_set_self_attr(2), both of which go through do_setattr(), and the name
is parsed before the change_profile permission is checked.
The query_label() path behind the securityfs .access file, which is
mode 0666, performs no permission check at all. Every component has to
resolve to a loaded profile, so a system with policy loaded is required.

The other two VEC_FLAG_TERMINATE users work on a label vec that
aa_label_alloc() has already sized with "+ 1 for null terminator entry on
vec". Reserve the same entry in vec_setup() and DEFINE_VEC(). Passing
len + 1 from the caller instead would move len == LOCAL_VEC_ENTRIES out of
the local array and into kzalloc().

Fixes: f1bd904175e8 ("apparmor: add the base fns() for domain labels")
Cc: stable@vger.kernel.org
Signed-off-by: Hyunwoo Kim &lt;imv4bel@gmail.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: fix cred UAF caused by begin_current_label_crit_section()</title>
<updated>2026-09-07T15:22:21+00:00</updated>
<author>
<name>Jann Horn</name>
<email>jannh@google.com</email>
</author>
<published>2026-08-06T15:55:02+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=587a6a92b93ec314c583bbf747413af170d42540'/>
<id>587a6a92b93ec314c583bbf747413af170d42540</id>
<content type='text'>
commit 3f4ae5fab613dca01d6a2a8210dd832e009fcf47 upstream.

AppArmor's begin_current_label_crit_section() is a scary function called
from lots of LSM hooks (in particular VFS/socket-related ones) that checks
if the label referenced by the current creds is marked FLAG_STALE, and if
so, attempts to use aa_replace_current_label() to replace the creds with an
updated version that uses a new label.

The first problem with this is that it would directly lead to UAF of
`struct cred` if anything in the kernel takes a pointer to the current
creds and accesses these past a security hook invocation that replaces
creds, like so:
```
const struct cred *cred = current_cred();
alloc_file_pseudo(...);
uid_t uid = cred-&gt;euid;
```
I don't know if anything in the kernel actually does this, but I think it
is very surprising that this pattern could lead to UAF.

The second problem is that things go wrong when aa_replace_current_label()
runs with overridden credentials. aa_replace_current_label() bails out if
`current_cred() != current_real_cred()` (mirroring the check in
proc_pid_attr_write()), but this check can't actually reliably detect
overridden credentials because the overridden creds can be the same as the
objective creds.

So in approximately the following scenario, things go wrong:

1. task begins with &lt;creds A&gt; (as both objective and subjective creds),
   with refcount=2
2. task grabs an extra reference on &lt;creds A&gt; for overriding
3. task calls override_creds(&lt;creds A&gt;), which returns a pointer to the old
   subjective creds (&lt;creds A&gt;)
4. task enters AppArmor LSM hook
5. AppArmor checks that objective/subjective creds are equal
6. AppArmor replaces both cred pointers with &lt;creds B&gt; and drops 2 refs on
   &lt;creds A&gt;
7. task leaves AppArmor LSM hook
8. task calls revert_creds(&lt;creds A&gt;)
9. now task-&gt;cred is &lt;creds A&gt; while task-&gt;real_cred is &lt;creds B&gt;, but the
   task_struct logically holds two references to &lt;creds B&gt;
10. another task drops the extra reference on &lt;creds A&gt; that was used for
    overriding, refcount drops to 0
11. now task-&gt;real_cred points to freed creds

At this point, any access to current_cred() will be UAF.

I have a test case where I run aa-disable on a profile while a process
using that profile is blocked on splice() from a FUSE passthrough file into
a full pipe; after the profile update, the pipe becomes empty, splice()
resumes, the credentials go out of sync, and a subsequent getuid() syscall
results in a KASAN UAF splat.

To fix this, instead of directly replacing creds, do it via task_work that
will run at the end of the current syscall. (The point in time at which the
cred replacement happens should have no correctness impact; it is just a
performance optimization to avoid unnecessarily touching the refcount of
the new label.)

Note that AppArmor still performs direct cred replacements in the
sb_pivotroot LSM hook after this change, and that direct cred replacements
can still happen in VFS -&gt;write() callbacks via proc_pid_attr_write().

There are two options for what to do with aa_dup_task_ctx(): Either
explicitly reset new-&gt;label_replacement_pending after the entire
aa_task_ctx has been copied, or switch to manually copying members over.
I am switching to manually copying members over because that should make
bugs more obvious.

Cc: stable@vger.kernel.org
Fixes: c75afcd153f6 ("AppArmor: contexts used in attaching policy to system objects")
Signed-off-by: Jann Horn &lt;jannh@google.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
commit 3f4ae5fab613dca01d6a2a8210dd832e009fcf47 upstream.

AppArmor's begin_current_label_crit_section() is a scary function called
from lots of LSM hooks (in particular VFS/socket-related ones) that checks
if the label referenced by the current creds is marked FLAG_STALE, and if
so, attempts to use aa_replace_current_label() to replace the creds with an
updated version that uses a new label.

The first problem with this is that it would directly lead to UAF of
`struct cred` if anything in the kernel takes a pointer to the current
creds and accesses these past a security hook invocation that replaces
creds, like so:
```
const struct cred *cred = current_cred();
alloc_file_pseudo(...);
uid_t uid = cred-&gt;euid;
```
I don't know if anything in the kernel actually does this, but I think it
is very surprising that this pattern could lead to UAF.

The second problem is that things go wrong when aa_replace_current_label()
runs with overridden credentials. aa_replace_current_label() bails out if
`current_cred() != current_real_cred()` (mirroring the check in
proc_pid_attr_write()), but this check can't actually reliably detect
overridden credentials because the overridden creds can be the same as the
objective creds.

So in approximately the following scenario, things go wrong:

1. task begins with &lt;creds A&gt; (as both objective and subjective creds),
   with refcount=2
2. task grabs an extra reference on &lt;creds A&gt; for overriding
3. task calls override_creds(&lt;creds A&gt;), which returns a pointer to the old
   subjective creds (&lt;creds A&gt;)
4. task enters AppArmor LSM hook
5. AppArmor checks that objective/subjective creds are equal
6. AppArmor replaces both cred pointers with &lt;creds B&gt; and drops 2 refs on
   &lt;creds A&gt;
7. task leaves AppArmor LSM hook
8. task calls revert_creds(&lt;creds A&gt;)
9. now task-&gt;cred is &lt;creds A&gt; while task-&gt;real_cred is &lt;creds B&gt;, but the
   task_struct logically holds two references to &lt;creds B&gt;
10. another task drops the extra reference on &lt;creds A&gt; that was used for
    overriding, refcount drops to 0
11. now task-&gt;real_cred points to freed creds

At this point, any access to current_cred() will be UAF.

I have a test case where I run aa-disable on a profile while a process
using that profile is blocked on splice() from a FUSE passthrough file into
a full pipe; after the profile update, the pipe becomes empty, splice()
resumes, the credentials go out of sync, and a subsequent getuid() syscall
results in a KASAN UAF splat.

To fix this, instead of directly replacing creds, do it via task_work that
will run at the end of the current syscall. (The point in time at which the
cred replacement happens should have no correctness impact; it is just a
performance optimization to avoid unnecessarily touching the refcount of
the new label.)

Note that AppArmor still performs direct cred replacements in the
sb_pivotroot LSM hook after this change, and that direct cred replacements
can still happen in VFS -&gt;write() callbacks via proc_pid_attr_write().

There are two options for what to do with aa_dup_task_ctx(): Either
explicitly reset new-&gt;label_replacement_pending after the entire
aa_task_ctx has been copied, or switch to manually copying members over.
I am switching to manually copying members over because that should make
bugs more obvious.

Cc: stable@vger.kernel.org
Fixes: c75afcd153f6 ("AppArmor: contexts used in attaching policy to system objects")
Signed-off-by: Jann Horn &lt;jannh@google.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Greg Kroah-Hartman &lt;gregkh@linuxfoundation.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: fix label can not be immediately before a declaration</title>
<updated>2026-07-24T14:16:27+00:00</updated>
<author>
<name>John Johansen</name>
<email>john.johansen@canonical.com</email>
</author>
<published>2026-06-14T23:16:59+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=85873b1bd3664af5cba608a014cd2df930d77f3e'/>
<id>85873b1bd3664af5cba608a014cd2df930d77f3e</id>
<content type='text'>
[ Upstream commit 1ed40bd525c00d22af666016af9aef7167f8085f ]

Fix error reported by kernel test robot

security/apparmor/policy.c:1381:2: error: a label can only be part of
a statement and a declaration is not a statement

All errors (new ones prefixed by &gt;&gt;):

   security/apparmor/policy.c: In function 'aa_replace_profiles':
&gt;&gt; security/apparmor/policy.c:1381:2: error: a label can only be part
   of a statement and a declaration is not a statement
     ssize_t udata_sz = udata-&gt;size;
     ^~~~~

Reported-by: kernel test robot &lt;lkp@intel.com&gt;
Closes: https://lore.kernel.org/oe-kbuild-all/202606150525.npax8WiH-lkp@intel.com/
Fixes: 7b42f95813dc9 ("apparmor: fix potential UAF in aa_replace_profiles")
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 1ed40bd525c00d22af666016af9aef7167f8085f ]

Fix error reported by kernel test robot

security/apparmor/policy.c:1381:2: error: a label can only be part of
a statement and a declaration is not a statement

All errors (new ones prefixed by &gt;&gt;):

   security/apparmor/policy.c: In function 'aa_replace_profiles':
&gt;&gt; security/apparmor/policy.c:1381:2: error: a label can only be part
   of a statement and a declaration is not a statement
     ssize_t udata_sz = udata-&gt;size;
     ^~~~~

Reported-by: kernel test robot &lt;lkp@intel.com&gt;
Closes: https://lore.kernel.org/oe-kbuild-all/202606150525.npax8WiH-lkp@intel.com/
Fixes: 7b42f95813dc9 ("apparmor: fix potential UAF in aa_replace_profiles")
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: fix uninitialised pointer passed to audit_log_untrustedstring()</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Maciek Borzecki</name>
<email>maciek.borzecki@gmail.com</email>
</author>
<published>2026-05-08T08:30:16+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=2791dd42d41e38805572b12116f721c97c4fcc0c'/>
<id>2791dd42d41e38805572b12116f721c97c4fcc0c</id>
<content type='text'>
[ Upstream commit bcd1b34c21748531a3febaf7440632b89d8deab7 ]

Commit 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
intrdouced a small bug, where path_name() may pass a potentially uninitialized
*name to aa_audit_file() if the path-&gt;dentry had been replaced with
aa_null.dentry earlier on. This can lead to page fault like one observed on
7.0.2 openSUSE Tumbleweed kernel:

[51692.242756] [  T24690] BUG: unable to handle page fault for address: 0000000f00000003
[51692.242762] [  T24690] #PF: supervisor read access in kernel mode
[51692.242763] [  T24690] #PF: error_code(0x0000) - not-present page
[51692.242765] [  T24690] PGD 0 P4D 0
[51692.242768] [  T24690] Oops: Oops: 0000 [#1] SMP NOPTI
[51692.242772] [  T24690] CPU: 3 UID: 1020 PID: 24690 Comm: snap-confine Tainted: G           O        7.0.2-1-default #1 PREEMPT(full) openSUSE Tumbleweed  ab90b4c9940707f9cafa19bdad80b2cec52dbe51
[51692.242775] [  T24690] Tainted: [O]=OOT_MODULE
[51692.242777] [  T24690] Hardware name: Framework Laptop 13 (AMD Ryzen 7040Series)/FRANMDCP05, BIOS 03.18 01/08/2026
[51692.242778] [  T24690] RIP: 0010:strlen+0x4/0x30
[51692.242783] [  T24690] Code: f7 75 ec 31 c0 e9 17 9f 00 ff 48 89 f8 e9 0f 9f 00 ff 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa &lt;80&gt; 3f 00 74 18 48 89 f8 0f 1f 40 00 48 83 c0 01 80 38 00 75 f7 48
[51692.242785] [  T24690] RSP: 0018:ffffd015eb1e3608 EFLAGS: 00010282
[51692.242787] [  T24690] RAX: 0000000000000000 RBX: ffff89796198a360 RCX: 0000000000000000
[51692.242788] [  T24690] RDX: 00000000000000d1 RSI: 0000000f00000003 RDI: 0000000f00000003
[51692.242790] [  T24690] RBP: ffffffffb7ede090 R08: 00000000000005f5 R09: 0000000000000000
[51692.242791] [  T24690] R10: 0000000000000000 R11: 0000000000000000 R12: ffffd015eb1e3700
[51692.242792] [  T24690] R13: ffff8977a22bc380 R14: ffffffffb7ec5190 R15: ffff8977a0c8aa80
[51692.242794] [  T24690] FS:  0000000000000000(0000) GS:ffff897f640d8000(0000) knlGS:0000000000000000
[51692.242796] [  T24690] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[51692.242797] [  T24690] CR2: 0000000f00000003 CR3: 00000006ad15f000 CR4: 0000000000f50ef0
[51692.242799] [  T24690] PKRU: 55555554
[51692.242800] [  T24690] Call Trace:
[51692.242802] [  T24690]  &lt;TASK&gt;
[51692.242804] [  T24690]  audit_log_untrustedstring+0x1d/0x40
[51692.242811] [  T24690]  common_lsm_audit+0x71/0x1d0
[51692.242816] [  T24690]  aa_audit+0x5a/0x170
[51692.242819] [  T24690]  aa_audit_file+0x18a/0x1b0
[51692.242825] [  T24690]  path_name+0xd2/0x100
[51692.242829] [  T24690]  profile_path_perm.part.0+0x58/0xb0
[51692.242832] [  T24690]  aa_path_perm+0xef/0x150
[51692.242837] [  T24690]  apparmor_file_open+0x153/0x2e0
[51692.242840] [  T24690]  security_file_open+0x46/0xd0
[51692.242844] [  T24690]  do_dentry_open+0xe9/0x4d0
[51692.242848] [  T24690]  vfs_open+0x30/0x100

While here, initialise variables which are passed down to path_name().

Fixes: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
Signed-off-by: Maciek Borzecki &lt;maciek.borzecki@gmail.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit bcd1b34c21748531a3febaf7440632b89d8deab7 ]

Commit 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
intrdouced a small bug, where path_name() may pass a potentially uninitialized
*name to aa_audit_file() if the path-&gt;dentry had been replaced with
aa_null.dentry earlier on. This can lead to page fault like one observed on
7.0.2 openSUSE Tumbleweed kernel:

[51692.242756] [  T24690] BUG: unable to handle page fault for address: 0000000f00000003
[51692.242762] [  T24690] #PF: supervisor read access in kernel mode
[51692.242763] [  T24690] #PF: error_code(0x0000) - not-present page
[51692.242765] [  T24690] PGD 0 P4D 0
[51692.242768] [  T24690] Oops: Oops: 0000 [#1] SMP NOPTI
[51692.242772] [  T24690] CPU: 3 UID: 1020 PID: 24690 Comm: snap-confine Tainted: G           O        7.0.2-1-default #1 PREEMPT(full) openSUSE Tumbleweed  ab90b4c9940707f9cafa19bdad80b2cec52dbe51
[51692.242775] [  T24690] Tainted: [O]=OOT_MODULE
[51692.242777] [  T24690] Hardware name: Framework Laptop 13 (AMD Ryzen 7040Series)/FRANMDCP05, BIOS 03.18 01/08/2026
[51692.242778] [  T24690] RIP: 0010:strlen+0x4/0x30
[51692.242783] [  T24690] Code: f7 75 ec 31 c0 e9 17 9f 00 ff 48 89 f8 e9 0f 9f 00 ff 0f 1f 40 00 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 f3 0f 1e fa &lt;80&gt; 3f 00 74 18 48 89 f8 0f 1f 40 00 48 83 c0 01 80 38 00 75 f7 48
[51692.242785] [  T24690] RSP: 0018:ffffd015eb1e3608 EFLAGS: 00010282
[51692.242787] [  T24690] RAX: 0000000000000000 RBX: ffff89796198a360 RCX: 0000000000000000
[51692.242788] [  T24690] RDX: 00000000000000d1 RSI: 0000000f00000003 RDI: 0000000f00000003
[51692.242790] [  T24690] RBP: ffffffffb7ede090 R08: 00000000000005f5 R09: 0000000000000000
[51692.242791] [  T24690] R10: 0000000000000000 R11: 0000000000000000 R12: ffffd015eb1e3700
[51692.242792] [  T24690] R13: ffff8977a22bc380 R14: ffffffffb7ec5190 R15: ffff8977a0c8aa80
[51692.242794] [  T24690] FS:  0000000000000000(0000) GS:ffff897f640d8000(0000) knlGS:0000000000000000
[51692.242796] [  T24690] CS:  0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[51692.242797] [  T24690] CR2: 0000000f00000003 CR3: 00000006ad15f000 CR4: 0000000000f50ef0
[51692.242799] [  T24690] PKRU: 55555554
[51692.242800] [  T24690] Call Trace:
[51692.242802] [  T24690]  &lt;TASK&gt;
[51692.242804] [  T24690]  audit_log_untrustedstring+0x1d/0x40
[51692.242811] [  T24690]  common_lsm_audit+0x71/0x1d0
[51692.242816] [  T24690]  aa_audit+0x5a/0x170
[51692.242819] [  T24690]  aa_audit_file+0x18a/0x1b0
[51692.242825] [  T24690]  path_name+0xd2/0x100
[51692.242829] [  T24690]  profile_path_perm.part.0+0x58/0xb0
[51692.242832] [  T24690]  aa_path_perm+0xef/0x150
[51692.242837] [  T24690]  apparmor_file_open+0x153/0x2e0
[51692.242840] [  T24690]  security_file_open+0x46/0xd0
[51692.242844] [  T24690]  do_dentry_open+0xe9/0x4d0
[51692.242848] [  T24690]  vfs_open+0x30/0x100

While here, initialise variables which are passed down to path_name().

Fixes: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
Signed-off-by: Maciek Borzecki &lt;maciek.borzecki@gmail.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: don't audit files pointing to aa_null.dentry</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Georgia Garcia</name>
<email>georgia.garcia@canonical.com</email>
</author>
<published>2026-05-28T19:04:12+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=fdf610a9a9e72e9f63a6ac7c9ea1d8e5a6002b57'/>
<id>fdf610a9a9e72e9f63a6ac7c9ea1d8e5a6002b57</id>
<content type='text'>
[ Upstream commit add2b70038bea194bcdef8a680f9153ee7f93ac0 ]

In
  commit 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
there was a change to not audit files pointing to
aa_null.dentry because they provide no value, but setting the error
variable instead of returning -EACCES was still causing them to be
audited.

Fixes: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
Acked-by: David Disseldorp &lt;ddiss@suse.de&gt;
Signed-off-by: Georgia Garcia &lt;georgia.garcia@canonical.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit add2b70038bea194bcdef8a680f9153ee7f93ac0 ]

In
  commit 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
there was a change to not audit files pointing to
aa_null.dentry because they provide no value, but setting the error
variable instead of returning -EACCES was still causing them to be
audited.

Fixes: 4a134723f9f1 ("apparmor: move check for aa_null file to cover all cases")
Acked-by: David Disseldorp &lt;ddiss@suse.de&gt;
Signed-off-by: Georgia Garcia &lt;georgia.garcia@canonical.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: put secmark label after secid lookup</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Zygmunt Krynicki</name>
<email>me@zygoon.pl</email>
</author>
<published>2026-05-05T03:40:53+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=b58d240883dfef8734a9d36fa333b049e2766ac0'/>
<id>b58d240883dfef8734a9d36fa333b049e2766ac0</id>
<content type='text'>
[ Upstream commit 340372688bb87da45ff8d4e2f82ccfd1b64c65ff ]

apparmor_secmark_init() parses a configured secmark label to obtain its
secid.  aa_label_strn_parse() returns a refcounted label, but the success
path kept that reference after copying the secid.

Fixes: ab9f2115081a ("apparmor: Allow filtering based on secmark policy")
Signed-off-by: Zygmunt Krynicki &lt;me@zygoon.pl&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 340372688bb87da45ff8d4e2f82ccfd1b64c65ff ]

apparmor_secmark_init() parses a configured secmark label to obtain its
secid.  aa_label_strn_parse() returns a refcounted label, but the success
path kept that reference after copying the secid.

Fixes: ab9f2115081a ("apparmor: Allow filtering based on secmark policy")
Signed-off-by: Zygmunt Krynicki &lt;me@zygoon.pl&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: aa_getprocattr free procattr leak on format failure</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Zygmunt Krynicki</name>
<email>me@zygoon.pl</email>
</author>
<published>2026-05-02T11:37:14+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=66a6c61369d4120d6d988ec0eb07d0340f6a5acb'/>
<id>66a6c61369d4120d6d988ec0eb07d0340f6a5acb</id>
<content type='text'>
[ Upstream commit fea23bf73f0cae8ccb1d0684e4a3003874771f41 ]

aa_getprocattr() allocates the output string before rendering the label
into it. If the second aa_label_snxprint() call fails, the function
returned without freeing that allocation.

Free and clear the output pointer on the uncommon formatting failure path
before dropping the namespace reference.

Fixes: 76a1d263aba3 ("apparmor: switch getprocattr to using label_print fns()")
Reviewed-by: Tyler Hicks &lt;code@thicks.com&gt;
Reviewed-by: Ryan Lee &lt;ryan.lee@canonical.com&gt;
Signed-off-by: Zygmunt Krynicki &lt;me@zygoon.pl&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit fea23bf73f0cae8ccb1d0684e4a3003874771f41 ]

aa_getprocattr() allocates the output string before rendering the label
into it. If the second aa_label_snxprint() call fails, the function
returned without freeing that allocation.

Free and clear the output pointer on the uncommon formatting failure path
before dropping the namespace reference.

Fixes: 76a1d263aba3 ("apparmor: switch getprocattr to using label_print fns()")
Reviewed-by: Tyler Hicks &lt;code@thicks.com&gt;
Reviewed-by: Ryan Lee &lt;ryan.lee@canonical.com&gt;
Signed-off-by: Zygmunt Krynicki &lt;me@zygoon.pl&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: fail policy unpack on accept2 allocation failure</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Zygmunt Krynicki</name>
<email>me@zygoon.pl</email>
</author>
<published>2026-05-04T06:32:37+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=22dc9433d458cff1270f120685114a9753e0ad1b'/>
<id>22dc9433d458cff1270f120685114a9753e0ad1b</id>
<content type='text'>
[ Upstream commit 45cf568241048e560a81aa2053f06a62069f5640 ]

unpack_pdb() may need to allocate a missing ACCEPT2 table for older policy
data. If that allocation failed, it set an error message but jumped to the
success path, returning a policydb with the required table missing.

Return -ENOMEM through the normal failure path when the ACCEPT2 allocation
fails. Remove the now-unused out label.

Fixes: 2e12c5f06017 ("apparmor: add additional flags to extended permission.")
Reviewed-by: Ryan Lee &lt;ryan.lee@canonical.com&gt;
Signed-off-by: Zygmunt Krynicki &lt;me@zygoon.pl&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 45cf568241048e560a81aa2053f06a62069f5640 ]

unpack_pdb() may need to allocate a missing ACCEPT2 table for older policy
data. If that allocation failed, it set an error message but jumped to the
success path, returning a policydb with the required table missing.

Return -ENOMEM through the normal failure path when the ACCEPT2 allocation
fails. Remove the now-unused out label.

Fixes: 2e12c5f06017 ("apparmor: add additional flags to extended permission.")
Reviewed-by: Ryan Lee &lt;ryan.lee@canonical.com&gt;
Signed-off-by: Zygmunt Krynicki &lt;me@zygoon.pl&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: Fix return in ns_mkdir_op</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Hongling Zeng</name>
<email>zenghongling@kylinos.cn</email>
</author>
<published>2026-05-03T04:12:43+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=3b918f6f5239087cf9f9224c356a1eb37dfcf46d'/>
<id>3b918f6f5239087cf9f9224c356a1eb37dfcf46d</id>
<content type='text'>
[ Upstream commit b7a2b49bba4e5994a476c49d662b796818079e5e ]

Return NULL instead of passing to ERR_PTR while error is zero.
  Fixes smatch warning:
    - security/apparmor/apparmorfs.c:1846 ns_mkdir_op() warn:
      passing zero to 'ERR_PTR'

Fixes: 88d5baf69082 ("Change inode_operations.mkdir to return struct dentry *")
Reviewed-by: Ryan Lee &lt;ryan.lee@canonical.com&gt;
Signed-off-by: Hongling Zeng &lt;zenghongling@kylinos.cn&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit b7a2b49bba4e5994a476c49d662b796818079e5e ]

Return NULL instead of passing to ERR_PTR while error is zero.
  Fixes smatch warning:
    - security/apparmor/apparmorfs.c:1846 ns_mkdir_op() warn:
      passing zero to 'ERR_PTR'

Fixes: 88d5baf69082 ("Change inode_operations.mkdir to return struct dentry *")
Reviewed-by: Ryan Lee &lt;ryan.lee@canonical.com&gt;
Signed-off-by: Hongling Zeng &lt;zenghongling@kylinos.cn&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
<entry>
<title>apparmor: remove or add symlinks to rawdata according to export_binary</title>
<updated>2026-07-24T14:16:26+00:00</updated>
<author>
<name>Georgia Garcia</name>
<email>georgia.garcia@canonical.com</email>
</author>
<published>2026-01-29T18:39:42+00:00</published>
<link rel='alternate' type='text/html' href='https://git.tavy.me/linux-stable.git/commit/?id=566d1ef98a7115026ef3c96c9d71c390aca29def'/>
<id>566d1ef98a7115026ef3c96c9d71c390aca29def</id>
<content type='text'>
[ Upstream commit 59fe6fbc4cd45582bc8893de0a382a36562317b3 ]

When the export_binary parameter is set, then rawdata is available and
there should be a symbolic link for the rawdata in the profile
directory in apparmorfs. If the parameter is unset, then the symlinks
should not exist.

The issue arises when changing the value of export_binary on runtime
and replacing profiles. If export_binary was set when the profile was
originally loaded, then changed to 0 and the profile was reloaded,
then the symbolic links would still exist but would return ENOENT
because the rawdata no longer exists.

On the opposite side, if export_binary was unset when the profile was
originally loaded, then changed to 1 and the profile was reloaded,
then the symbolic links would not exist, even though the rawdata does.

Fixes: d61c57fde8191 ("apparmor: make export of raw binary profile to userspace optional")
Signed-off-by: Georgia Garcia &lt;georgia.garcia@canonical.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</content>
<content type='xhtml'>
<div xmlns='http://www.w3.org/1999/xhtml'>
<pre>
[ Upstream commit 59fe6fbc4cd45582bc8893de0a382a36562317b3 ]

When the export_binary parameter is set, then rawdata is available and
there should be a symbolic link for the rawdata in the profile
directory in apparmorfs. If the parameter is unset, then the symlinks
should not exist.

The issue arises when changing the value of export_binary on runtime
and replacing profiles. If export_binary was set when the profile was
originally loaded, then changed to 0 and the profile was reloaded,
then the symbolic links would still exist but would return ENOENT
because the rawdata no longer exists.

On the opposite side, if export_binary was unset when the profile was
originally loaded, then changed to 1 and the profile was reloaded,
then the symbolic links would not exist, even though the rawdata does.

Fixes: d61c57fde8191 ("apparmor: make export of raw binary profile to userspace optional")
Signed-off-by: Georgia Garcia &lt;georgia.garcia@canonical.com&gt;
Signed-off-by: John Johansen &lt;john.johansen@canonical.com&gt;
Signed-off-by: Sasha Levin &lt;sashal@kernel.org&gt;
</pre>
</div>
</content>
</entry>
</feed>
