lkml.org 
[lkml]   [2019]   [May]   [30]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.0 128/346] mm/uaccess: Use unsigned long to placate UBSAN warnings on older GCC versions
    Date
    [ 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 <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>
    Signed-off-by: Sasha Levin <sashal@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 58eacd41526c5..023ba9f3b99f0 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 1c1a1b0e38a5f..7f2db3fe311fd 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


    \
     
     \ /
      Last update: 2019-05-30 06:31    [W:4.748 / U:0.740 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site