diff mbox series

[v7,02/11] powerpc: prepare string/mem functions for KASAN

Message ID 42ee601ffe33df4652808b09caae6824edf1b667.1551098214.git.christophe.leroy@c-s.fr (mailing list archive)
State New, archived
Headers show
Series KASAN for powerpc/32 | expand

Commit Message

Christophe Leroy Feb. 25, 2019, 1:48 p.m. UTC
CONFIG_KASAN implements wrappers for memcpy() memmove() and memset()
Those wrappers are doing the verification then call respectively
__memcpy() __memmove() and __memset(). The arches are therefore
expected to rename their optimised functions that way.

For files on which KASAN is inhibited, #defines are used to allow
them to directly call optimised versions of the functions without
going through the KASAN wrappers.

See 393f203f5fd5 ("x86_64: kasan: add interceptors for
memset/memmove/memcpy functions") for details.

Other string / mem functions do not (yet) have kasan wrappers,
we therefore have to fallback to the generic versions when
KASAN is active, otherwise KASAN checks will be skipped.

Signed-off-by: Christophe Leroy <christophe.leroy@c-s.fr>
---
 arch/powerpc/include/asm/kasan.h       | 15 +++++++++++++++
 arch/powerpc/include/asm/string.h      | 32 +++++++++++++++++++++++++++++---
 arch/powerpc/kernel/prom_init_check.sh | 10 +++++++++-
 arch/powerpc/lib/Makefile              | 11 ++++++++---
 arch/powerpc/lib/copy_32.S             | 15 +++++++++------
 arch/powerpc/lib/mem_64.S              | 10 ++++++----
 arch/powerpc/lib/memcpy_64.S           |  4 ++--
 7 files changed, 78 insertions(+), 19 deletions(-)
 create mode 100644 arch/powerpc/include/asm/kasan.h

Comments

kernel test robot Feb. 25, 2019, 10:47 p.m. UTC | #1
Hi Christophe,

Thank you for the patch! Yet something to improve:

[auto build test ERROR on powerpc/next]
[also build test ERROR on v5.0-rc8]
[cannot apply to next-20190225]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]

url:    https://github.com/0day-ci/linux/commits/Christophe-Leroy/KASAN-for-powerpc-32/20190226-052610
base:   https://git.kernel.org/pub/scm/linux/kernel/git/powerpc/linux.git next
config: powerpc-defconfig (attached as .config)
compiler: powerpc64-linux-gnu-gcc (Debian 8.2.0-11) 8.2.0
reproduce:
        wget https://raw.githubusercontent.com/intel/lkp-tests/master/sbin/make.cross -O ~/bin/make.cross
        chmod +x ~/bin/make.cross
        # save the attached .config to linux build tree
        GCC_VERSION=8.2.0 make.cross ARCH=powerpc 

All errors (new ones prefixed by >>):

   arch/powerpc/lib/mem_64.S: Assembler messages:
>> arch/powerpc/lib/mem_64.S:35: Error: unrecognized opcode: `_global_kasan(memset)'
>> arch/powerpc/lib/mem_64.S:100: Error: unrecognized opcode: `export_symbol_kasan(memset)'
>> arch/powerpc/lib/mem_64.S:102: Error: unrecognized opcode: `_global_toc_kasan(memmove)'
>> arch/powerpc/lib/mem_64.S:143: Error: unrecognized opcode: `export_symbol_kasan(memmove)'
--
   arch/powerpc/lib/memcpy_64.S: Assembler messages:
>> arch/powerpc/lib/memcpy_64.S:21: Error: unrecognized opcode: `_global_toc_kasan(memcpy)'
>> arch/powerpc/lib/memcpy_64.S:232: Error: unrecognized opcode: `export_symbol_kasan(memcpy)'

vim +35 arch/powerpc/lib/mem_64.S

    34	
  > 35	_GLOBAL_KASAN(memset)
    36		neg	r0,r3
    37		rlwimi	r4,r4,8,16,23
    38		andi.	r0,r0,7			/* # bytes to be 8-byte aligned */
    39		rlwimi	r4,r4,16,0,15
    40		cmplw	cr1,r5,r0		/* do we get that far? */
    41		rldimi	r4,r4,32,0
    42	.Lms:	PPC_MTOCRF(1,r0)
    43		mr	r6,r3
    44		blt	cr1,8f
    45		beq	3f			/* if already 8-byte aligned */
    46		subf	r5,r0,r5
    47		bf	31,1f
    48		stb	r4,0(r6)
    49		addi	r6,r6,1
    50	1:	bf	30,2f
    51		sth	r4,0(r6)
    52		addi	r6,r6,2
    53	2:	bf	29,3f
    54		stw	r4,0(r6)
    55		addi	r6,r6,4
    56	3:	srdi.	r0,r5,6
    57		clrldi	r5,r5,58
    58		mtctr	r0
    59		beq	5f
    60		.balign 16
    61	4:	std	r4,0(r6)
    62		std	r4,8(r6)
    63		std	r4,16(r6)
    64		std	r4,24(r6)
    65		std	r4,32(r6)
    66		std	r4,40(r6)
    67		std	r4,48(r6)
    68		std	r4,56(r6)
    69		addi	r6,r6,64
    70		bdnz	4b
    71	5:	srwi.	r0,r5,3
    72		clrlwi	r5,r5,29
    73		PPC_MTOCRF(1,r0)
    74		beq	8f
    75		bf	29,6f
    76		std	r4,0(r6)
    77		std	r4,8(r6)
    78		std	r4,16(r6)
    79		std	r4,24(r6)
    80		addi	r6,r6,32
    81	6:	bf	30,7f
    82		std	r4,0(r6)
    83		std	r4,8(r6)
    84		addi	r6,r6,16
    85	7:	bf	31,8f
    86		std	r4,0(r6)
    87		addi	r6,r6,8
    88	8:	cmpwi	r5,0
    89		PPC_MTOCRF(1,r5)
    90		beqlr
    91		bf	29,9f
    92		stw	r4,0(r6)
    93		addi	r6,r6,4
    94	9:	bf	30,10f
    95		sth	r4,0(r6)
    96		addi	r6,r6,2
    97	10:	bflr	31
    98		stb	r4,0(r6)
    99		blr
 > 100	EXPORT_SYMBOL_KASAN(memset)
   101	
 > 102	_GLOBAL_TOC_KASAN(memmove)
   103		cmplw	0,r3,r4
   104		bgt	backwards_memcpy
   105		b	memcpy
   106	
   107	_GLOBAL(backwards_memcpy)
   108		rlwinm.	r7,r5,32-3,3,31		/* r0 = r5 >> 3 */
   109		add	r6,r3,r5
   110		add	r4,r4,r5
   111		beq	2f
   112		andi.	r0,r6,3
   113		mtctr	r7
   114		bne	5f
   115		.balign 16
   116	1:	lwz	r7,-4(r4)
   117		lwzu	r8,-8(r4)
   118		stw	r7,-4(r6)
   119		stwu	r8,-8(r6)
   120		bdnz	1b
   121		andi.	r5,r5,7
   122	2:	cmplwi	0,r5,4
   123		blt	3f
   124		lwzu	r0,-4(r4)
   125		subi	r5,r5,4
   126		stwu	r0,-4(r6)
   127	3:	cmpwi	0,r5,0
   128		beqlr
   129		mtctr	r5
   130	4:	lbzu	r0,-1(r4)
   131		stbu	r0,-1(r6)
   132		bdnz	4b
   133		blr
   134	5:	mtctr	r0
   135	6:	lbzu	r7,-1(r4)
   136		stbu	r7,-1(r6)
   137		bdnz	6b
   138		subf	r5,r0,r5
   139		rlwinm.	r7,r5,32-3,3,31
   140		beq	2b
   141		mtctr	r7
   142		b	1b
 > 143	EXPORT_SYMBOL_KASAN(memmove)

---
0-DAY kernel test infrastructure                Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all                   Intel Corporation
diff mbox series

Patch

diff --git a/arch/powerpc/include/asm/kasan.h b/arch/powerpc/include/asm/kasan.h
new file mode 100644
index 000000000000..2efd0e42cfc9
--- /dev/null
+++ b/arch/powerpc/include/asm/kasan.h
@@ -0,0 +1,15 @@ 
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef __ASM_KASAN_H
+#define __ASM_KASAN_H
+
+#ifdef CONFIG_KASAN
+#define _GLOBAL_KASAN(fn)	.weak fn ; _GLOBAL(__##fn) ; _GLOBAL(fn)
+#define _GLOBAL_KASAN_TOC(fn)	.weak fn ; _GLOBAL_TOC(__##fn) ; _GLOBAL_TOC(fn)
+#define EXPORT_SYMBOL_KASAN(fn)	EXPORT_SYMBOL(__##fn) ; EXPORT_SYMBOL(fn)
+#else
+#define _GLOBAL_KASAN(fn)	_GLOBAL(fn)
+#define _GLOBAL_KASAN_TOC(fn)	_GLOBAL_TOC(fn)
+#define EXPORT_SYMBOL_KASAN(fn)	EXPORT_SYMBOL(fn)
+#endif
+
+#endif
diff --git a/arch/powerpc/include/asm/string.h b/arch/powerpc/include/asm/string.h
index 1647de15a31e..9bf6dffb4090 100644
--- a/arch/powerpc/include/asm/string.h
+++ b/arch/powerpc/include/asm/string.h
@@ -4,14 +4,17 @@ 
 
 #ifdef __KERNEL__
 
+#ifndef CONFIG_KASAN
 #define __HAVE_ARCH_STRNCPY
 #define __HAVE_ARCH_STRNCMP
+#define __HAVE_ARCH_MEMCHR
+#define __HAVE_ARCH_MEMCMP
+#define __HAVE_ARCH_MEMSET16
+#endif
+
 #define __HAVE_ARCH_MEMSET
 #define __HAVE_ARCH_MEMCPY
 #define __HAVE_ARCH_MEMMOVE
-#define __HAVE_ARCH_MEMCMP
-#define __HAVE_ARCH_MEMCHR
-#define __HAVE_ARCH_MEMSET16
 #define __HAVE_ARCH_MEMCPY_FLUSHCACHE
 
 extern char * strcpy(char *,const char *);
@@ -27,7 +30,27 @@  extern int memcmp(const void *,const void *,__kernel_size_t);
 extern void * memchr(const void *,int,__kernel_size_t);
 extern void * memcpy_flushcache(void *,const void *,__kernel_size_t);
 
+void *__memset(void *s, int c, __kernel_size_t count);
+void *__memcpy(void *to, const void *from, __kernel_size_t n);
+void *__memmove(void *to, const void *from, __kernel_size_t n);
+
+#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)
+/*
+ * For files that are not instrumented (e.g. mm/slub.c) we
+ * should use not instrumented version of mem* functions.
+ */
+#define memcpy(dst, src, len) __memcpy(dst, src, len)
+#define memmove(dst, src, len) __memmove(dst, src, len)
+#define memset(s, c, n) __memset(s, c, n)
+
+#ifndef __NO_FORTIFY
+#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */
+#endif
+
+#endif
+
 #ifdef CONFIG_PPC64
+#ifndef CONFIG_KASAN
 #define __HAVE_ARCH_MEMSET32
 #define __HAVE_ARCH_MEMSET64
 
@@ -49,8 +72,11 @@  static inline void *memset64(uint64_t *p, uint64_t v, __kernel_size_t n)
 {
 	return __memset64(p, v, n * 8);
 }
+#endif
 #else
+#ifndef CONFIG_KASAN
 #define __HAVE_ARCH_STRLEN
+#endif
 
 extern void *memset16(uint16_t *, uint16_t, __kernel_size_t);
 #endif
diff --git a/arch/powerpc/kernel/prom_init_check.sh b/arch/powerpc/kernel/prom_init_check.sh
index 667df97d2595..181fd10008ef 100644
--- a/arch/powerpc/kernel/prom_init_check.sh
+++ b/arch/powerpc/kernel/prom_init_check.sh
@@ -16,8 +16,16 @@ 
 # If you really need to reference something from prom_init.o add
 # it to the list below:
 
+grep "^CONFIG_KASAN=y$" .config >/dev/null
+if [ $? -eq 0 ]
+then
+	MEM_FUNCS="__memcpy __memset"
+else
+	MEM_FUNCS="memcpy memset"
+fi
+
 WHITELIST="add_reloc_offset __bss_start __bss_stop copy_and_flush
-_end enter_prom memcpy memset reloc_offset __secondary_hold
+_end enter_prom $MEM_FUNCS reloc_offset __secondary_hold
 __secondary_hold_acknowledge __secondary_hold_spinloop __start
 strcmp strcpy strlcpy strlen strncmp strstr kstrtobool logo_linux_clut224
 reloc_got2 kernstart_addr memstart_addr linux_banner _stext
diff --git a/arch/powerpc/lib/Makefile b/arch/powerpc/lib/Makefile
index 79396e184bca..47a4de434c22 100644
--- a/arch/powerpc/lib/Makefile
+++ b/arch/powerpc/lib/Makefile
@@ -8,9 +8,14 @@  ccflags-$(CONFIG_PPC64)	:= $(NO_MINIMAL_TOC)
 CFLAGS_REMOVE_code-patching.o = $(CC_FLAGS_FTRACE)
 CFLAGS_REMOVE_feature-fixups.o = $(CC_FLAGS_FTRACE)
 
-obj-y += string.o alloc.o code-patching.o feature-fixups.o
+obj-y += alloc.o code-patching.o feature-fixups.o
 
-obj-$(CONFIG_PPC32)	+= div64.o copy_32.o crtsavres.o strlen_32.o
+ifndef CONFIG_KASAN
+obj-y	+=	string.o memcmp_$(BITS).o
+obj-$(CONFIG_PPC32)	+= strlen_32.o
+endif
+
+obj-$(CONFIG_PPC32)	+= div64.o copy_32.o crtsavres.o
 
 obj-$(CONFIG_FUNCTION_ERROR_INJECTION)	+= error-inject.o
 
@@ -34,7 +39,7 @@  obj64-$(CONFIG_KPROBES_SANITY_TEST)	+= test_emulate_step.o \
 					   test_emulate_step_exec_instr.o
 
 obj-y			+= checksum_$(BITS).o checksum_wrappers.o \
-			   string_$(BITS).o memcmp_$(BITS).o
+			   string_$(BITS).o
 
 obj-y			+= sstep.o ldstfp.o quad.o
 obj64-y			+= quad.o
diff --git a/arch/powerpc/lib/copy_32.S b/arch/powerpc/lib/copy_32.S
index ba66846fe973..fc4fa7246200 100644
--- a/arch/powerpc/lib/copy_32.S
+++ b/arch/powerpc/lib/copy_32.S
@@ -14,6 +14,7 @@ 
 #include <asm/ppc_asm.h>
 #include <asm/export.h>
 #include <asm/code-patching-asm.h>
+#include <asm/kasan.h>
 
 #define COPY_16_BYTES		\
 	lwz	r7,4(r4);	\
@@ -68,6 +69,7 @@  CACHELINE_BYTES = L1_CACHE_BYTES
 LG_CACHELINE_BYTES = L1_CACHE_SHIFT
 CACHELINE_MASK = (L1_CACHE_BYTES-1)
 
+#ifndef CONFIG_KASAN
 _GLOBAL(memset16)
 	rlwinm.	r0 ,r5, 31, 1, 31
 	addi	r6, r3, -4
@@ -81,6 +83,7 @@  _GLOBAL(memset16)
 	sth	r4, 4(r6)
 	blr
 EXPORT_SYMBOL(memset16)
+#endif
 
 /*
  * Use dcbz on the complete cache lines in the destination
@@ -91,7 +94,7 @@  EXPORT_SYMBOL(memset16)
  * We therefore skip the optimised bloc that uses dcbz. This jump is
  * replaced by a nop once cache is active. This is done in machine_init()
  */
-_GLOBAL(memset)
+_GLOBAL_KASAN(memset)
 	cmplwi	0,r5,4
 	blt	7f
 
@@ -150,7 +153,7 @@  _GLOBAL(memset)
 9:	stbu	r4,1(r6)
 	bdnz	9b
 	blr
-EXPORT_SYMBOL(memset)
+EXPORT_SYMBOL_KASAN(memset)
 
 /*
  * This version uses dcbz on the complete cache lines in the
@@ -163,12 +166,12 @@  EXPORT_SYMBOL(memset)
  * We therefore jump to generic_memcpy which doesn't use dcbz. This jump is
  * replaced by a nop once cache is active. This is done in machine_init()
  */
-_GLOBAL(memmove)
+_GLOBAL_KASAN(memmove)
 	cmplw	0,r3,r4
 	bgt	backwards_memcpy
 	/* fall through */
 
-_GLOBAL(memcpy)
+_GLOBAL_KASAN(memcpy)
 1:	b	generic_memcpy
 	patch_site	1b, patch__memcpy_nocache
 
@@ -242,8 +245,8 @@  _GLOBAL(memcpy)
 	stbu	r0,1(r6)
 	bdnz	40b
 65:	blr
-EXPORT_SYMBOL(memcpy)
-EXPORT_SYMBOL(memmove)
+EXPORT_SYMBOL_KASAN(memcpy)
+EXPORT_SYMBOL_KASAN(memmove)
 
 generic_memcpy:
 	srwi.	r7,r5,3
diff --git a/arch/powerpc/lib/mem_64.S b/arch/powerpc/lib/mem_64.S
index 3c3be02f33b7..aa02a0abf96c 100644
--- a/arch/powerpc/lib/mem_64.S
+++ b/arch/powerpc/lib/mem_64.S
@@ -13,6 +13,7 @@ 
 #include <asm/ppc_asm.h>
 #include <asm/export.h>
 
+#ifndef CONFIG_KASAN
 _GLOBAL(__memset16)
 	rlwimi	r4,r4,16,0,15
 	/* fall through */
@@ -29,8 +30,9 @@  _GLOBAL(__memset64)
 EXPORT_SYMBOL(__memset16)
 EXPORT_SYMBOL(__memset32)
 EXPORT_SYMBOL(__memset64)
+#endif
 
-_GLOBAL(memset)
+_GLOBAL_KASAN(memset)
 	neg	r0,r3
 	rlwimi	r4,r4,8,16,23
 	andi.	r0,r0,7			/* # bytes to be 8-byte aligned */
@@ -95,9 +97,9 @@  _GLOBAL(memset)
 10:	bflr	31
 	stb	r4,0(r6)
 	blr
-EXPORT_SYMBOL(memset)
+EXPORT_SYMBOL_KASAN(memset)
 
-_GLOBAL_TOC(memmove)
+_GLOBAL_TOC_KASAN(memmove)
 	cmplw	0,r3,r4
 	bgt	backwards_memcpy
 	b	memcpy
@@ -138,4 +140,4 @@  _GLOBAL(backwards_memcpy)
 	beq	2b
 	mtctr	r7
 	b	1b
-EXPORT_SYMBOL(memmove)
+EXPORT_SYMBOL_KASAN(memmove)
diff --git a/arch/powerpc/lib/memcpy_64.S b/arch/powerpc/lib/memcpy_64.S
index 273ea67e60a1..2d5358cee711 100644
--- a/arch/powerpc/lib/memcpy_64.S
+++ b/arch/powerpc/lib/memcpy_64.S
@@ -18,7 +18,7 @@ 
 #endif
 
 	.align	7
-_GLOBAL_TOC(memcpy)
+_GLOBAL_TOC_KASAN(memcpy)
 BEGIN_FTR_SECTION
 #ifdef __LITTLE_ENDIAN__
 	cmpdi	cr7,r5,0
@@ -229,4 +229,4 @@  END_FTR_SECTION_IFCLR(CPU_FTR_UNALIGNED_LD_STD)
 4:	ld	r3,-STACKFRAMESIZE+STK_REG(R31)(r1)	/* return dest pointer */
 	blr
 #endif
-EXPORT_SYMBOL(memcpy)
+EXPORT_SYMBOL_KASAN(memcpy)