diff options
author | Peter Zijlstra <peterz@infradead.org> | 2019-04-24 03:19:25 -0400 |
---|---|---|
committer | Ingo Molnar <mingo@kernel.org> | 2019-04-24 06:19:45 -0400 |
commit | 29da93fea3ea39ab9b12270cc6be1b70ef201c9e (patch) | |
tree | 1d5dd50a2abb3145a22d6a398cafad8f9067de90 | |
parent | 6ae865615fc43d014da2fd1f1bba7e81ee622d1b (diff) |
mm/uaccess: Use 'unsigned long' to placate UBSAN warnings on older GCC versions
Randy reported objtool triggered on his (GCC-7.4) build:
lib/strncpy_from_user.o: warning: objtool: strncpy_from_user()+0x315: call to __ubsan_handle_add_overflow() with UACCESS enabled
lib/strnlen_user.o: warning: objtool: strnlen_user()+0x337: call to __ubsan_handle_sub_overflow() with UACCESS enabled
This is due to UBSAN generating signed-overflow-UB warnings where it
should not. Prior to GCC-8 UBSAN ignored -fwrapv (which the kernel
uses through -fno-strict-overflow).
Make the functions use 'unsigned long' throughout.
Reported-by: Randy Dunlap <rdunlap@infradead.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Randy Dunlap <rdunlap@infradead.org> # build-tested
Acked-by: Linus Torvalds <torvalds@linux-foundation.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Thomas Gleixner <tglx@linutronix.de>
Cc: luto@kernel.org
Link: http://lkml.kernel.org/r/20190424072208.754094071@infradead.org
Signed-off-by: Ingo Molnar <mingo@kernel.org>
-rw-r--r-- | lib/strncpy_from_user.c | 5 | ||||
-rw-r--r-- | lib/strnlen_user.c | 4 |
2 files changed, 5 insertions, 4 deletions
diff --git a/lib/strncpy_from_user.c b/lib/strncpy_from_user.c index 58eacd41526c..023ba9f3b99f 100644 --- a/lib/strncpy_from_user.c +++ b/lib/strncpy_from_user.c | |||
@@ -23,10 +23,11 @@ | |||
23 | * hit it), 'max' is the address space maximum (and we return | 23 | * hit it), 'max' is the address space maximum (and we return |
24 | * -EFAULT if we hit it). | 24 | * -EFAULT if we hit it). |
25 | */ | 25 | */ |
26 | static inline long do_strncpy_from_user(char *dst, const char __user *src, long count, unsigned long max) | 26 | static inline long do_strncpy_from_user(char *dst, const char __user *src, |
27 | unsigned long count, unsigned long max) | ||
27 | { | 28 | { |
28 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; | 29 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; |
29 | long res = 0; | 30 | unsigned long res = 0; |
30 | 31 | ||
31 | /* | 32 | /* |
32 | * Truncate 'max' to the user-specified limit, so that | 33 | * Truncate 'max' to the user-specified limit, so that |
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c index 1c1a1b0e38a5..7f2db3fe311f 100644 --- a/lib/strnlen_user.c +++ b/lib/strnlen_user.c | |||
@@ -28,7 +28,7 @@ | |||
28 | static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) | 28 | static inline long do_strnlen_user(const char __user *src, unsigned long count, unsigned long max) |
29 | { | 29 | { |
30 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; | 30 | const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS; |
31 | long align, res = 0; | 31 | unsigned long align, res = 0; |
32 | unsigned long c; | 32 | unsigned long c; |
33 | 33 | ||
34 | /* | 34 | /* |
@@ -42,7 +42,7 @@ static inline long do_strnlen_user(const char __user *src, unsigned long count, | |||
42 | * Do everything aligned. But that means that we | 42 | * Do everything aligned. But that means that we |
43 | * need to also expand the maximum.. | 43 | * need to also expand the maximum.. |
44 | */ | 44 | */ |
45 | align = (sizeof(long) - 1) & (unsigned long)src; | 45 | align = (sizeof(unsigned long) - 1) & (unsigned long)src; |
46 | src -= align; | 46 | src -= align; |
47 | max += align; | 47 | max += align; |
48 | 48 | ||