arm64: lib: use C string functions with KASAN enabled

ARM64 has asm implementation of memchr(), memcmp(), str[r]chr(),
str[n]cmp(), str[n]len().  KASAN don't see memory accesses in asm code,
thus it can potentially miss many bugs.

Ifdef out __HAVE_ARCH_* defines of these functions when KASAN is enabled,
so the generic implementations from lib/string.c will be used.

We can't just remove the asm functions because efistub uses them.  And we
can't have two non-weak functions either, so declare the asm functions as
weak.

Link: http://lkml.kernel.org/r/20180920135631.23833-2-aryabinin@virtuozzo.com
Signed-off-by: Andrey Ryabinin <aryabinin@virtuozzo.com>
Reported-by: Kyeongdon Kim <kyeongdon.kim@lge.com>
Cc: Alexander Potapenko <glider@google.com>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Dmitry Vyukov <dvyukov@google.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
This commit is contained in:
Andrey Ryabinin 2018-10-26 15:02:30 -07:00 committed by Linus Torvalds
parent 74f213ea25
commit 19a2ca0fb5
10 changed files with 21 additions and 16 deletions

View File

@ -16,6 +16,7 @@
#ifndef __ASM_STRING_H #ifndef __ASM_STRING_H
#define __ASM_STRING_H #define __ASM_STRING_H
#ifndef CONFIG_KASAN
#define __HAVE_ARCH_STRRCHR #define __HAVE_ARCH_STRRCHR
extern char *strrchr(const char *, int c); extern char *strrchr(const char *, int c);
@ -34,6 +35,13 @@ extern __kernel_size_t strlen(const char *);
#define __HAVE_ARCH_STRNLEN #define __HAVE_ARCH_STRNLEN
extern __kernel_size_t strnlen(const char *, __kernel_size_t); extern __kernel_size_t strnlen(const char *, __kernel_size_t);
#define __HAVE_ARCH_MEMCMP
extern int memcmp(const void *, const void *, size_t);
#define __HAVE_ARCH_MEMCHR
extern void *memchr(const void *, int, __kernel_size_t);
#endif
#define __HAVE_ARCH_MEMCPY #define __HAVE_ARCH_MEMCPY
extern void *memcpy(void *, const void *, __kernel_size_t); extern void *memcpy(void *, const void *, __kernel_size_t);
extern void *__memcpy(void *, const void *, __kernel_size_t); extern void *__memcpy(void *, const void *, __kernel_size_t);
@ -42,16 +50,10 @@ extern void *__memcpy(void *, const void *, __kernel_size_t);
extern void *memmove(void *, const void *, __kernel_size_t); extern void *memmove(void *, const void *, __kernel_size_t);
extern void *__memmove(void *, const void *, __kernel_size_t); extern void *__memmove(void *, const void *, __kernel_size_t);
#define __HAVE_ARCH_MEMCHR
extern void *memchr(const void *, int, __kernel_size_t);
#define __HAVE_ARCH_MEMSET #define __HAVE_ARCH_MEMSET
extern void *memset(void *, int, __kernel_size_t); extern void *memset(void *, int, __kernel_size_t);
extern void *__memset(void *, int, __kernel_size_t); extern void *__memset(void *, int, __kernel_size_t);
#define __HAVE_ARCH_MEMCMP
extern int memcmp(const void *, const void *, size_t);
#ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE #ifdef CONFIG_ARCH_HAS_UACCESS_FLUSHCACHE
#define __HAVE_ARCH_MEMCPY_FLUSHCACHE #define __HAVE_ARCH_MEMCPY_FLUSHCACHE
void memcpy_flushcache(void *dst, const void *src, size_t cnt); void memcpy_flushcache(void *dst, const void *src, size_t cnt);

View File

@ -44,20 +44,23 @@ EXPORT_SYMBOL(__arch_copy_in_user);
EXPORT_SYMBOL(memstart_addr); EXPORT_SYMBOL(memstart_addr);
/* string / mem functions */ /* string / mem functions */
#ifndef CONFIG_KASAN
EXPORT_SYMBOL(strchr); EXPORT_SYMBOL(strchr);
EXPORT_SYMBOL(strrchr); EXPORT_SYMBOL(strrchr);
EXPORT_SYMBOL(strcmp); EXPORT_SYMBOL(strcmp);
EXPORT_SYMBOL(strncmp); EXPORT_SYMBOL(strncmp);
EXPORT_SYMBOL(strlen); EXPORT_SYMBOL(strlen);
EXPORT_SYMBOL(strnlen); EXPORT_SYMBOL(strnlen);
EXPORT_SYMBOL(memcmp);
EXPORT_SYMBOL(memchr);
#endif
EXPORT_SYMBOL(memset); EXPORT_SYMBOL(memset);
EXPORT_SYMBOL(memcpy); EXPORT_SYMBOL(memcpy);
EXPORT_SYMBOL(memmove); EXPORT_SYMBOL(memmove);
EXPORT_SYMBOL(__memset); EXPORT_SYMBOL(__memset);
EXPORT_SYMBOL(__memcpy); EXPORT_SYMBOL(__memcpy);
EXPORT_SYMBOL(__memmove); EXPORT_SYMBOL(__memmove);
EXPORT_SYMBOL(memchr);
EXPORT_SYMBOL(memcmp);
/* atomic bitops */ /* atomic bitops */
EXPORT_SYMBOL(set_bit); EXPORT_SYMBOL(set_bit);

View File

@ -30,7 +30,7 @@
* Returns: * Returns:
* x0 - address of first occurrence of 'c' or 0 * x0 - address of first occurrence of 'c' or 0
*/ */
ENTRY(memchr) WEAK(memchr)
and w1, w1, #0xff and w1, w1, #0xff
1: subs x2, x2, #1 1: subs x2, x2, #1
b.mi 2f b.mi 2f

View File

@ -58,7 +58,7 @@ pos .req x11
limit_wd .req x12 limit_wd .req x12
mask .req x13 mask .req x13
ENTRY(memcmp) WEAK(memcmp)
cbz limit, .Lret0 cbz limit, .Lret0
eor tmp1, src1, src2 eor tmp1, src1, src2
tst tmp1, #7 tst tmp1, #7

View File

@ -29,7 +29,7 @@
* Returns: * Returns:
* x0 - address of first occurrence of 'c' or 0 * x0 - address of first occurrence of 'c' or 0
*/ */
ENTRY(strchr) WEAK(strchr)
and w1, w1, #0xff and w1, w1, #0xff
1: ldrb w2, [x0], #1 1: ldrb w2, [x0], #1
cmp w2, w1 cmp w2, w1

View File

@ -60,7 +60,7 @@ tmp3 .req x9
zeroones .req x10 zeroones .req x10
pos .req x11 pos .req x11
ENTRY(strcmp) WEAK(strcmp)
eor tmp1, src1, src2 eor tmp1, src1, src2
mov zeroones, #REP8_01 mov zeroones, #REP8_01
tst tmp1, #7 tst tmp1, #7

View File

@ -56,7 +56,7 @@ pos .req x12
#define REP8_7f 0x7f7f7f7f7f7f7f7f #define REP8_7f 0x7f7f7f7f7f7f7f7f
#define REP8_80 0x8080808080808080 #define REP8_80 0x8080808080808080
ENTRY(strlen) WEAK(strlen)
mov zeroones, #REP8_01 mov zeroones, #REP8_01
bic src, srcin, #15 bic src, srcin, #15
ands tmp1, srcin, #15 ands tmp1, srcin, #15

View File

@ -64,7 +64,7 @@ limit_wd .req x13
mask .req x14 mask .req x14
endloop .req x15 endloop .req x15
ENTRY(strncmp) WEAK(strncmp)
cbz limit, .Lret0 cbz limit, .Lret0
eor tmp1, src1, src2 eor tmp1, src1, src2
mov zeroones, #REP8_01 mov zeroones, #REP8_01

View File

@ -59,7 +59,7 @@ limit_wd .req x14
#define REP8_7f 0x7f7f7f7f7f7f7f7f #define REP8_7f 0x7f7f7f7f7f7f7f7f
#define REP8_80 0x8080808080808080 #define REP8_80 0x8080808080808080
ENTRY(strnlen) WEAK(strnlen)
cbz limit, .Lhit_limit cbz limit, .Lhit_limit
mov zeroones, #REP8_01 mov zeroones, #REP8_01
bic src, srcin, #15 bic src, srcin, #15

View File

@ -29,7 +29,7 @@
* Returns: * Returns:
* x0 - address of last occurrence of 'c' or 0 * x0 - address of last occurrence of 'c' or 0
*/ */
ENTRY(strrchr) WEAK(strrchr)
mov x3, #0 mov x3, #0
and w1, w1, #0xff and w1, w1, #0xff
1: ldrb w2, [x0], #1 1: ldrb w2, [x0], #1