VYPR
Unrated severityNVD Advisory· Published Jun 3, 2026

CVE-2026-46254

CVE-2026-46254

Description

Linux kernel AppArmor component has an unaligned memory access vulnerability when handling DFA tables, potentially leading to system instability.

AI Insight

LLM-synthesized narrative grounded in this CVE's description and references.

Linux kernel AppArmor component has an unaligned memory access vulnerability when handling DFA tables, potentially leading to system instability.

Vulnerability

The Linux kernel's AppArmor component is vulnerable to an unaligned memory access issue when processing DFA tables. These tables, which can originate from kernel or userspace, may not always be 8-byte aligned, triggering the vulnerability on various architectures. This issue affects versions of the Linux kernel prior to the fix.

Exploitation

An attacker could potentially trigger this vulnerability by providing a malformed DFA table to the AppArmor subsystem, likely through the apparmor_parser utility or by manipulating profile updates. This would require the ability to interact with the system in a way that allows for the loading or modification of AppArmor profiles, such as having write access to specific files or the ability to execute apparmor_parser.

Impact

Successful exploitation of this vulnerability can lead to a kernel warning and an unaligned access message, indicating a potential for system instability or a denial of service. The specific impact may vary depending on the architecture and the exact nature of the unaligned access, but it could potentially lead to a kernel panic.

Mitigation

This vulnerability has been resolved in the Linux kernel by implementing the get_unaligned_xx() helpers to correctly handle unaligned DFA tables. The fix is available in the Linux kernel versions that incorporate the changes detailed in reference [1]. There are no workarounds mentioned other than applying the patch. The affected versions are not explicitly listed, but the fix is available in the stable kernel tree.

AI Insight generated on Jun 3, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.

Affected products

1

Patches

8
23f112bd6144

AppArmor: Allow apparmor to handle unaligned dfa tables

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitHelge DellerNov 25, 2025Fixed in 6.18.14via kernel-cna
1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index c5a91600842a1..26e82ba879d44 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
64802f731214

AppArmor: Allow apparmor to handle unaligned dfa tables

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitHelge DellerNov 25, 2025Fixed in 7.0via kernel-cna
1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index c5a91600842a1..26e82ba879d44 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
ec737e7fdf2f

AppArmor: Allow apparmor to handle unaligned dfa tables

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitHelge DellerNov 25, 2025Fixed in 6.12.75via kernel-cna
1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index 12e036f8ce0f7..4f998715d2942 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -277,14 +278,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -293,7 +294,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
cded636008bd

AppArmor: Allow apparmor to handle unaligned dfa tables

https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.gitHelge DellerNov 25, 2025Fixed in 6.19.4via kernel-cna
1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index c5a91600842a1..26e82ba879d44 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
ec737e7fdf2f

AppArmor: Allow apparmor to handle unaligned dfa tables

1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index 12e036f8ce0f7..4f998715d2942 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -277,14 +278,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -293,7 +294,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
cded636008bd

AppArmor: Allow apparmor to handle unaligned dfa tables

1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index c5a91600842a1..26e82ba879d44 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
23f112bd6144

AppArmor: Allow apparmor to handle unaligned dfa tables

1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index c5a91600842a1..26e82ba879d44 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    
64802f731214

AppArmor: Allow apparmor to handle unaligned dfa tables

1 file changed · +8 8
  • security/apparmor/match.c+8 8 modified
    diff --git a/security/apparmor/match.c b/security/apparmor/match.c
    index c5a91600842a1..26e82ba879d44 100644
    --- a/security/apparmor/match.c
    +++ b/security/apparmor/match.c
    @@ -15,6 +15,7 @@
     #include <linux/vmalloc.h>
     #include <linux/err.h>
     #include <linux/kref.h>
    +#include <linux/unaligned.h>
     
     #include "include/lib.h"
     #include "include/match.h"
    @@ -42,11 +43,11 @@ static struct table_header *unpack_table(char *blob, size_t bsize)
     	/* loaded td_id's start at 1, subtract 1 now to avoid doing
     	 * it every time we use td_id as an index
     	 */
    -	th.td_id = be16_to_cpu(*(__be16 *) (blob)) - 1;
    +	th.td_id = get_unaligned_be16(blob) - 1;
     	if (th.td_id > YYTD_ID_MAX)
     		goto out;
    -	th.td_flags = be16_to_cpu(*(__be16 *) (blob + 2));
    -	th.td_lolen = be32_to_cpu(*(__be32 *) (blob + 8));
    +	th.td_flags = get_unaligned_be16(blob + 2);
    +	th.td_lolen = get_unaligned_be32(blob + 8);
     	blob += sizeof(struct table_header);
     
     	if (!(th.td_flags == YYTD_DATA16 || th.td_flags == YYTD_DATA32 ||
    @@ -313,14 +314,14 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	if (size < sizeof(struct table_set_header))
     		goto fail;
     
    -	if (ntohl(*(__be32 *) data) != YYTH_MAGIC)
    +	if (get_unaligned_be32(data) != YYTH_MAGIC)
     		goto fail;
     
    -	hsize = ntohl(*(__be32 *) (data + 4));
    +	hsize = get_unaligned_be32(data + 4);
     	if (size < hsize)
     		goto fail;
     
    -	dfa->flags = ntohs(*(__be16 *) (data + 12));
    +	dfa->flags = get_unaligned_be16(data + 12);
     	if (dfa->flags & ~(YYTH_FLAGS))
     		goto fail;
     
    @@ -329,7 +330,7 @@ struct aa_dfa *aa_dfa_unpack(void *blob, size_t size, int flags)
     	 * if (dfa->flags & YYTH_FLAGS_OOB_TRANS) {
     	 *	if (hsize < 16 + 4)
     	 *		goto fail;
    -	 *	dfa->max_oob = ntol(*(__be32 *) (data + 16));
    +	 *	dfa->max_oob = get_unaligned_be32(data + 16);
     	 *	if (dfa->max <= MAX_OOB_SUPPORTED) {
     	 *		pr_err("AppArmor DFA OOB greater than supported\n");
     	 *		goto fail;
    -- 
    cgit 1.3-korg
    
    
    

Vulnerability mechanics

Root cause

"The AppArmor module incorrectly handles unaligned DFA tables, leading to memory access violations."

Attack vector

An attacker can trigger this vulnerability by providing a malformed AppArmor DFA table during profile loading or replacement. This malformed data, which is not guaranteed to be 8-byte aligned, is then processed by the `aa_dfa_unpack` function. The subsequent unaligned memory access can lead to a kernel warning and crash.

Affected code

The vulnerability resides in the `aa_dfa_unpack` function within `security/apparmor/match.c`. Specifically, the code that unpacks the DFA table header and its associated data was performing direct memory reads that assumed 8-byte alignment. The patch modifies these read operations to use `get_unaligned_be16` and `get_unaligned_be32` functions, ensuring safe handling of potentially unaligned data [patch_id=4686679].

What the fix does

The patch addresses the vulnerability by replacing direct memory access with `get_unaligned_xx()` helper functions. These functions are designed to safely handle data that may not be aligned to specific memory boundaries. By using these helpers, the kernel can correctly unpack the DFA tables regardless of their alignment, preventing the unaligned memory access and subsequent crashes [patch_id=4686679].

Preconditions

  • inputThe attacker must be able to provide a crafted AppArmor DFA table.
  • configThe AppArmor security module must be enabled in the kernel.

Generated on Jun 3, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.

References

4

News mentions

1