| From 12e6db0161cccdf915b75e6250423e1686295a63 Mon Sep 17 00:00:00 2001 |
| From: Sasha Levin <sashal@kernel.org> |
| Date: Wed, 26 Nov 2025 21:15:04 +0100 |
| Subject: apparmor: Fix & Optimize table creation from possibly unaligned |
| memory |
| |
| From: Helge Deller <deller@kernel.org> |
| |
| [ Upstream commit 6fc367bfd4c8886e6b1742aabbd1c0bdc310db3a ] |
| |
| Source blob may come from userspace and might be unaligned. |
| Try to optize the copying process by avoiding unaligned memory accesses. |
| |
| - Added Fixes tag |
| - Added "Fix &" to description as this doesn't just optimize but fixes |
| a potential unaligned memory access |
| Fixes: e6e8bf418850d ("apparmor: fix restricted endian type warnings for dfa unpack") |
| Signed-off-by: Helge Deller <deller@gmx.de> |
| [jj: remove duplicate word "convert" in comment trigger checkpatch warning] |
| Signed-off-by: John Johansen <john.johansen@canonical.com> |
| Signed-off-by: Sasha Levin <sashal@kernel.org> |
| --- |
| security/apparmor/include/match.h | 12 +++++++----- |
| security/apparmor/match.c | 7 +++---- |
| 2 files changed, 10 insertions(+), 9 deletions(-) |
| |
| diff --git a/security/apparmor/include/match.h b/security/apparmor/include/match.h |
| index 1fbe82f5021b1..0dde8eda3d1a5 100644 |
| --- a/security/apparmor/include/match.h |
| +++ b/security/apparmor/include/match.h |
| @@ -104,16 +104,18 @@ struct aa_dfa { |
| struct table_header *tables[YYTD_ID_TSIZE]; |
| }; |
| |
| -#define byte_to_byte(X) (X) |
| - |
| #define UNPACK_ARRAY(TABLE, BLOB, LEN, TTYPE, BTYPE, NTOHX) \ |
| do { \ |
| typeof(LEN) __i; \ |
| TTYPE *__t = (TTYPE *) TABLE; \ |
| BTYPE *__b = (BTYPE *) BLOB; \ |
| - for (__i = 0; __i < LEN; __i++) { \ |
| - __t[__i] = NTOHX(__b[__i]); \ |
| - } \ |
| + BUILD_BUG_ON(sizeof(TTYPE) != sizeof(BTYPE)); \ |
| + if (IS_ENABLED(CONFIG_CPU_BIG_ENDIAN)) \ |
| + memcpy(__t, __b, (LEN) * sizeof(BTYPE)); \ |
| + else /* copy & convert from big-endian */ \ |
| + for (__i = 0; __i < LEN; __i++) { \ |
| + __t[__i] = NTOHX(&__b[__i]); \ |
| + } \ |
| } while (0) |
| |
| static inline size_t table_size(size_t len, size_t el_size) |
| diff --git a/security/apparmor/match.c b/security/apparmor/match.c |
| index 26e82ba879d44..bbeb3be68572f 100644 |
| --- a/security/apparmor/match.c |
| +++ b/security/apparmor/match.c |
| @@ -67,14 +67,13 @@ static struct table_header *unpack_table(char *blob, size_t bsize) |
| table->td_flags = th.td_flags; |
| table->td_lolen = th.td_lolen; |
| if (th.td_flags == YYTD_DATA8) |
| - UNPACK_ARRAY(table->td_data, blob, th.td_lolen, |
| - u8, u8, byte_to_byte); |
| + memcpy(table->td_data, blob, th.td_lolen); |
| else if (th.td_flags == YYTD_DATA16) |
| UNPACK_ARRAY(table->td_data, blob, th.td_lolen, |
| - u16, __be16, be16_to_cpu); |
| + u16, __be16, get_unaligned_be16); |
| else if (th.td_flags == YYTD_DATA32) |
| UNPACK_ARRAY(table->td_data, blob, th.td_lolen, |
| - u32, __be32, be32_to_cpu); |
| + u32, __be32, get_unaligned_be32); |
| else |
| goto fail; |
| /* if table was vmalloced make sure the page tables are synced |
| -- |
| 2.51.0 |
| |