CVE-2026-46055
Description
In the Linux kernel, the following vulnerability has been resolved:
apparmor: Fix string overrun due to missing termination
When booting Ubuntu 26.04 with Linux 7.0-rc4 on an ARM64 Qualcomm Snapdragon X1 we see a string buffer overrun:
BUG: KASAN: slab-out-of-bounds in aa_dfa_match (security/apparmor/match.c:535) Read of size 1 at addr ffff0008901cc000 by task snap-update-ns/2120
CPU: 5 UID: 60578 PID: 2120 Comm: snap-update-ns Not tainted 7.0.0-rc4+ #22 PREEMPTLAZY Hardware name: LENOVO 83ED/LNVNB161216, BIOS NHCN60WW 09/11/2025 Call trace: show_stack (arch/arm64/kernel/stacktrace.c:501) (C) dump_stack_lvl (lib/dump_stack.c:122) print_report (mm/kasan/report.c:379 mm/kasan/report.c:482) kasan_report (mm/kasan/report.c:597) __asan_report_load1_noabort (mm/kasan/report_generic.c:378) aa_dfa_match (security/apparmor/match.c:535) match_mnt_path_str (security/apparmor/mount.c:244 security/apparmor/mount.c:336) match_mnt (security/apparmor/mount.c:371) aa_bind_mount (security/apparmor/mount.c:447 (discriminator 4)) apparmor_sb_mount (security/apparmor/lsm.c:719 (discriminator 1)) security_sb_mount (security/security.c:1062 (discriminator 31)) path_mount (fs/namespace.c:4101) __arm64_sys_mount (fs/namespace.c:4172 fs/namespace.c:4361 fs/namespace.c:4338 fs/namespace.c:4338) invoke_syscall.constprop.0 (arch/arm64/kernel/syscall.c:35 arch/arm64/kernel/syscall.c:49) el0_svc_common.constprop.0 (./include/linux/thread_info.h:142 (discriminator 2) arch/arm64/kernel/syscall.c:140 (discriminator 2)) do_el0_svc (arch/arm64/kernel/syscall.c:152) el0_svc (arch/arm64/kernel/entry-common.c:80 arch/arm64/kernel/entry-common.c:725) el0t_64_sync_handler (arch/arm64/kernel/entry-common.c:744) el0t_64_sync (arch/arm64/kernel/entry.S:596)
Allocated by task 2120: kasan_save_stack (mm/kasan/common.c:58) kasan_save_track (./arch/arm64/include/asm/current.h:19 mm/kasan/common.c:70 mm/kasan/common.c:79) kasan_save_alloc_info (mm/kasan/generic.c:571) __kasan_kmalloc (mm/kasan/common.c:419) __kmalloc_noprof (./include/linux/kasan.h:263 mm/slub.c:5260 mm/slub.c:5272) aa_get_buffer (security/apparmor/lsm.c:2201) aa_bind_mount (security/apparmor/mount.c:442) apparmor_sb_mount (security/apparmor/lsm.c:719 (discriminator 1)) security_sb_mount (security/security.c:1062 (discriminator 31)) path_mount (fs/namespace.c:4101) __arm64_sys_mount (fs/namespace.c:4172 fs/namespace.c:4361 fs/namespace.c:4338 fs/namespace.c:4338) invoke_syscall.constprop.0 (arch/arm64/kernel/syscall.c:35 arch/arm64/kernel/syscall.c:49) el0_svc_common.constprop.0 (./include/linux/thread_info.h:142 (discriminator 2) arch/arm64/kernel/syscall.c:140 (discriminator 2)) do_el0_svc (arch/arm64/kernel/syscall.c:152) el0_svc (arch/arm64/kernel/entry-common.c:80 arch/arm64/kernel/entry-common.c:725) el0t_64_sync_handler (arch/arm64/kernel/entry-common.c:744) el0t_64_sync (arch/arm64/kernel/entry.S:596)
The buggy address belongs to the object at ffff0008901ca000 which belongs to the cache kmalloc-rnd-06-8k of size 8192 The buggy address is located 0 bytes to the right of allocated 8192-byte region [ffff0008901ca000, ffff0008901cc000)
The buggy address belongs to the physical page: page: refcount:0 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x9101c8 head: order:3 mapcount:0 entire_mapcount:0 nr_pages_mapped:-1 pincount:0 flags: 0x8000000000000040(head|zone=2) page_type: f5(slab) raw: 8000000000000040 ffff000800016c40 fffffdffe2d14e10 ffff000800015c70 raw: 0000000000000000 0000000800010001 00000000f5000000 0000000000000000 head: 8000000000000040 ffff000800016c40 fffffdffe2d14e10 ffff000800015c70 head: 0000000000000000 0000000800010001 00000000f5000000 0000000000000000 head: 8000000000000003 fffffdffe2407201 fffffdffffffffff 00000000ffffffff head: ffffffffffffffff 0000000000000000 00000000ffffffff 0000000000000008 page dumped because: kasan: bad access detected
Memory state around the buggy address: ffff0008901cbf00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ffff0008 ---truncated---
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Missing null termination in AppArmor's aa_dfa_match causes slab-out-of-bounds read, potentially leaking kernel memory or crashing the system.
Vulnerability
In the Linux kernel (version 7.0.0-rc4 and possibly earlier), the AppArmor security module contains a string buffer overrun vulnerability in security/apparmor/match.c within the aa_dfa_match function. The bug is due to missing null termination when handling mount path strings, leading to a slab-out-of-bounds read. The issue was discovered when booting Ubuntu 26.04 on ARM64 Qualcomm Snapdragon X1 hardware [1].
Exploitation
An attacker with the ability to trigger a mount operation (e.g., via mount() syscall) can cause the kernel to read beyond the allocated buffer. The call trace shows the vulnerability is reachable via aa_bind_mount and apparmor_sb_mount in the AppArmor LSM. No special privileges beyond the ability to perform mount operations are required; the attacker must be able to execute mount syscalls, which may require certain capabilities or user namespaces.
Impact
Successful exploitation results in a slab-out-of-bounds read, which can lead to information disclosure (KASAN report indicates reading beyond allocated memory) or a system crash (denial of service). The read is of size 1 byte from out-of-bounds memory, potentially leaking kernel memory contents.
Mitigation
The fix is included in a stable kernel commit [1]. Users should update to a kernel version containing the patch. As a workaround, users may restrict mount operations for unprivileged users or disable AppArmor if not required. No EOL status or KEV listing is known.
AI Insight generated on May 27, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
1Patches
44b877ef27adcapparmor: Fix string overrun due to missing termination
2 files changed · +10 −8
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
828bf7929bedapparmor: Fix string overrun due to missing termination
2 files changed · +10 −8
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
828bf7929bedapparmor: Fix string overrun due to missing termination
2 files changed · +10 −8
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
4b877ef27adcapparmor: Fix string overrun due to missing termination
2 files changed · +10 −8
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
security/apparmor/path.c+5 −4 modifieddiff --git a/security/apparmor/path.c b/security/apparmor/path.c index 65a0ca5cc1bdda..2494e810153841 100644 --- a/security/apparmor/path.c +++ b/security/apparmor/path.c @@ -164,14 +164,16 @@ static int d_namespace_path(const struct path *path, char *buf, char **name, } out: - /* Append "/" to directory paths, except for root "/" which - * already ends in a slash. + /* Append "/" to directory paths and reterminate string, except for + * root "/" which already ends in a slash. */ if (!error && isdir) { bool is_root = (*name)[0] == '/' && (*name)[1] == '\0'; - if (!is_root) + if (!is_root) { buf[aa_g_path_max - 2] = '/'; + buf[aa_g_path_max - 1] = '\0'; + } } return error; -- cgit 1.3-korg
Vulnerability mechanics
Root cause
"Missing null-termination after appending a '/' character to a directory path in d_namespace_path causes a string buffer overrun when the path is later used by aa_dfa_match."
Attack vector
An unprivileged user triggers the bug by calling the mount() syscall (e.g., via snap-update-ns) on a directory path. The AppArmor LSM hook apparmor_sb_mount calls aa_bind_mount, which allocates a buffer via aa_get_buffer and then invokes d_namespace_path in security/apparmor/path.c. When the path is a non-root directory, d_namespace_path writes a '/' at buf[aa_g_path_max - 2] but fails to write a null terminator at buf[aa_g_path_max - 1], leaving the buffer unterminated. The subsequent call to aa_dfa_match reads past the allocated region, causing a KASAN slab-out-of-bounds read [patch_id=2660084][patch_id=2660085].
Affected code
The vulnerable function is `d_namespace_path` in `security/apparmor/path.c`. When `isdir` is true and the path is not root, the code writes `buf[aa_g_path_max - 2] = '/'` but omits writing a null terminator at `buf[aa_g_path_max - 1]`, leaving the buffer unterminated [patch_id=2660084].
What the fix does
The patch adds `buf[aa_g_path_max - 1] = '\0';` inside the `if (!is_root)` block, ensuring the buffer is properly null-terminated after the '/' is appended. The comment is also updated to reflect that the code now both appends the slash and reterminates the string. This closes the overrun because aa_dfa_match will no longer read beyond the allocated buffer when scanning for the null terminator [patch_id=2660084][patch_id=2660085].
Preconditions
- configAppArmor LSM must be enabled and enforcing policy on the system.
- authThe attacker must be able to invoke the mount() syscall (e.g., as an unprivileged user via snap-update-ns).
- inputThe mount target path must be a non-root directory, causing d_namespace_path to append a '/'.
Generated on May 27, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
2News mentions
0No linked articles in our index yet.