Skip to content

Commit 1542026

Browse files
ardbiesheuvelRussell King (Oracle)
authored andcommitted
ARM: 9179/1: uaccess: avoid alignment faults in copy_[from|to]_kernel_nofault
The helpers that are used to implement copy_from_kernel_nofault() and copy_to_kernel_nofault() cast a void* to a pointer to a wider type, which may result in alignment faults on ARM if the compiler decides to use double-word or multiple-word load/store instructions. Only configurations that define CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS=y are affected, given that commit 2423de2 ("ARM: 9115/1: mm/maccess: fix unaligned copy_{from,to}_kernel_nofault") ensures that dst and src are sufficiently aligned otherwise. So use the unaligned accessors for accessing dst and src in cases where they may be misaligned. Cc: <stable@vger.kernel.org> # depends on 2423de2 Fixes: 2df4c9a ("ARM: 9112/1: uaccess: add __{get,put}_kernel_nofault") Reviewed-by: Arnd Bergmann <arnd@arndb.de> Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Russell King (Oracle) <rmk+kernel@armlinux.org.uk>
1 parent 8b59b0a commit 1542026

File tree

1 file changed

+8
-2
lines changed

1 file changed

+8
-2
lines changed

arch/arm/include/asm/uaccess.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/string.h>
1212
#include <asm/memory.h>
1313
#include <asm/domain.h>
14+
#include <asm/unaligned.h>
1415
#include <asm/unified.h>
1516
#include <asm/compiler.h>
1617

@@ -497,7 +498,10 @@ do { \
497498
} \
498499
default: __err = __get_user_bad(); break; \
499500
} \
500-
*(type *)(dst) = __val; \
501+
if (IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS)) \
502+
put_unaligned(__val, (type *)(dst)); \
503+
else \
504+
*(type *)(dst) = __val; /* aligned by caller */ \
501505
if (__err) \
502506
goto err_label; \
503507
} while (0)
@@ -507,7 +511,9 @@ do { \
507511
const type *__pk_ptr = (dst); \
508512
unsigned long __dst = (unsigned long)__pk_ptr; \
509513
int __err = 0; \
510-
type __val = *(type *)src; \
514+
type __val = IS_ENABLED(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) \
515+
? get_unaligned((type *)(src)) \
516+
: *(type *)(src); /* aligned by caller */ \
511517
switch (sizeof(type)) { \
512518
case 1: __put_user_asm_byte(__val, __dst, __err, ""); break; \
513519
case 2: __put_user_asm_half(__val, __dst, __err, ""); break; \

0 commit comments

Comments
 (0)