[ Upstream commit 29da93fea3ea39ab9b12270cc6be1b70ef201c9e ]

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 <rdun...@infradead.org>
Signed-off-by: Peter Zijlstra (Intel) <pet...@infradead.org>
Acked-by: Randy Dunlap <rdun...@infradead.org> # build-tested
Acked-by: Linus Torvalds <torva...@linux-foundation.org>
Cc: Peter Zijlstra <pet...@infradead.org>
Cc: Thomas Gleixner <t...@linutronix.de>
Cc: l...@kernel.org
Link: http://lkml.kernel.org/r/20190424072208.754094...@infradead.org
Signed-off-by: Ingo Molnar <mi...@kernel.org>
Signed-off-by: Sasha Levin <sas...@kernel.org>
---
 lib/strncpy_from_user.c | 5 +++--
 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 b53e1b5d80f42..e304b54c9c7dd 100644
--- a/lib/strncpy_from_user.c
+++ b/lib/strncpy_from_user.c
@@ -23,10 +23,11 @@
  * hit it), 'max' is the address space maximum (and we return
  * -EFAULT if we hit it).
  */
-static inline long do_strncpy_from_user(char *dst, const char __user *src, 
long count, unsigned long max)
+static inline long do_strncpy_from_user(char *dst, const char __user *src,
+                                       unsigned long count, unsigned long max)
 {
        const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
-       long res = 0;
+       unsigned long res = 0;
 
        /*
         * Truncate 'max' to the user-specified limit, so that
diff --git a/lib/strnlen_user.c b/lib/strnlen_user.c
index 60d0bbda8f5e5..184f80f7bacfa 100644
--- a/lib/strnlen_user.c
+++ b/lib/strnlen_user.c
@@ -28,7 +28,7 @@
 static inline long do_strnlen_user(const char __user *src, unsigned long 
count, unsigned long max)
 {
        const struct word_at_a_time constants = WORD_AT_A_TIME_CONSTANTS;
-       long align, res = 0;
+       unsigned long align, res = 0;
        unsigned long c;
 
        /*
@@ -42,7 +42,7 @@ static inline long do_strnlen_user(const char __user *src, 
unsigned long count,
         * Do everything aligned. But that means that we
         * need to also expand the maximum..
         */
-       align = (sizeof(long) - 1) & (unsigned long)src;
+       align = (sizeof(unsigned long) - 1) & (unsigned long)src;
        src -= align;
        max += align;
 
-- 
2.20.1



Reply via email to