summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVasily Gorbik <gor@linux.ibm.com>2018-12-13 09:53:48 -0500
committerMartin Schwidefsky <schwidefsky@de.ibm.com>2019-01-18 03:34:18 -0500
commit7e0d92f002460d30bea01fa7157be2f13af370a5 (patch)
treeef62cb72c7d7683f8e0bc4390d13195afc060afc
parent32b77252f47ec00c3c9dc4705f0197dd0f5f87d9 (diff)
s390/kasan: improve string/memory functions checks
Avoid using arch specific implementations of string/memory functions with KASAN since gcc cannot instrument asm code memory accesses and many bugs could be missed. Acked-by: Heiko Carstens <heiko.carstens@de.ibm.com> Signed-off-by: Vasily Gorbik <gor@linux.ibm.com> Signed-off-by: Martin Schwidefsky <schwidefsky@de.ibm.com>
-rw-r--r--arch/s390/boot/string.c1
-rw-r--r--arch/s390/include/asm/string.h28
-rw-r--r--arch/s390/lib/string.c28
3 files changed, 51 insertions, 6 deletions
diff --git a/arch/s390/boot/string.c b/arch/s390/boot/string.c
index 25aca07898ba..b11e8108773a 100644
--- a/arch/s390/boot/string.c
+++ b/arch/s390/boot/string.c
@@ -2,6 +2,7 @@
2#include <linux/ctype.h> 2#include <linux/ctype.h>
3#include <linux/kernel.h> 3#include <linux/kernel.h>
4#include <linux/errno.h> 4#include <linux/errno.h>
5#undef CONFIG_KASAN
5#include "../lib/string.c" 6#include "../lib/string.c"
6 7
7int strncmp(const char *cs, const char *ct, size_t count) 8int strncmp(const char *cs, const char *ct, size_t count)
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h
index 116cc15a4b8a..70d87db54e62 100644
--- a/arch/s390/include/asm/string.h
+++ b/arch/s390/include/asm/string.h
@@ -12,15 +12,21 @@
12#include <linux/types.h> 12#include <linux/types.h>
13#endif 13#endif
14 14
15#define __HAVE_ARCH_MEMCHR /* inline & arch function */
16#define __HAVE_ARCH_MEMCMP /* arch function */
17#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ 15#define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */
18#define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */ 16#define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */
19#define __HAVE_ARCH_MEMSCAN /* inline & arch function */
20#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ 17#define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */
21#define __HAVE_ARCH_MEMSET16 /* arch function */ 18#define __HAVE_ARCH_MEMSET16 /* arch function */
22#define __HAVE_ARCH_MEMSET32 /* arch function */ 19#define __HAVE_ARCH_MEMSET32 /* arch function */
23#define __HAVE_ARCH_MEMSET64 /* arch function */ 20#define __HAVE_ARCH_MEMSET64 /* arch function */
21
22void *memcpy(void *dest, const void *src, size_t n);
23void *memset(void *s, int c, size_t n);
24void *memmove(void *dest, const void *src, size_t n);
25
26#ifndef CONFIG_KASAN
27#define __HAVE_ARCH_MEMCHR /* inline & arch function */
28#define __HAVE_ARCH_MEMCMP /* arch function */
29#define __HAVE_ARCH_MEMSCAN /* inline & arch function */
24#define __HAVE_ARCH_STRCAT /* inline & arch function */ 30#define __HAVE_ARCH_STRCAT /* inline & arch function */
25#define __HAVE_ARCH_STRCMP /* arch function */ 31#define __HAVE_ARCH_STRCMP /* arch function */
26#define __HAVE_ARCH_STRCPY /* inline & arch function */ 32#define __HAVE_ARCH_STRCPY /* inline & arch function */
@@ -35,9 +41,6 @@
35 41
36/* Prototypes for non-inlined arch strings functions. */ 42/* Prototypes for non-inlined arch strings functions. */
37int memcmp(const void *s1, const void *s2, size_t n); 43int memcmp(const void *s1, const void *s2, size_t n);
38void *memcpy(void *dest, const void *src, size_t n);
39void *memset(void *s, int c, size_t n);
40void *memmove(void *dest, const void *src, size_t n);
41int strcmp(const char *s1, const char *s2); 44int strcmp(const char *s1, const char *s2);
42size_t strlcat(char *dest, const char *src, size_t n); 45size_t strlcat(char *dest, const char *src, size_t n);
43size_t strlcpy(char *dest, const char *src, size_t size); 46size_t strlcpy(char *dest, const char *src, size_t size);
@@ -45,6 +48,7 @@ char *strncat(char *dest, const char *src, size_t n);
45char *strncpy(char *dest, const char *src, size_t n); 48char *strncpy(char *dest, const char *src, size_t n);
46char *strrchr(const char *s, int c); 49char *strrchr(const char *s, int c);
47char *strstr(const char *s1, const char *s2); 50char *strstr(const char *s1, const char *s2);
51#endif /* !CONFIG_KASAN */
48 52
49#undef __HAVE_ARCH_STRCHR 53#undef __HAVE_ARCH_STRCHR
50#undef __HAVE_ARCH_STRNCHR 54#undef __HAVE_ARCH_STRNCHR
@@ -95,6 +99,7 @@ static inline void *memset64(uint64_t *s, uint64_t v, size_t count)
95 99
96#if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY)) 100#if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY))
97 101
102#ifdef __HAVE_ARCH_MEMCHR
98static inline void *memchr(const void * s, int c, size_t n) 103static inline void *memchr(const void * s, int c, size_t n)
99{ 104{
100 register int r0 asm("0") = (char) c; 105 register int r0 asm("0") = (char) c;
@@ -109,7 +114,9 @@ static inline void *memchr(const void * s, int c, size_t n)
109 : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); 114 : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory");
110 return (void *) ret; 115 return (void *) ret;
111} 116}
117#endif
112 118
119#ifdef __HAVE_ARCH_MEMSCAN
113static inline void *memscan(void *s, int c, size_t n) 120static inline void *memscan(void *s, int c, size_t n)
114{ 121{
115 register int r0 asm("0") = (char) c; 122 register int r0 asm("0") = (char) c;
@@ -121,7 +128,9 @@ static inline void *memscan(void *s, int c, size_t n)
121 : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); 128 : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory");
122 return (void *) ret; 129 return (void *) ret;
123} 130}
131#endif
124 132
133#ifdef __HAVE_ARCH_STRCAT
125static inline char *strcat(char *dst, const char *src) 134static inline char *strcat(char *dst, const char *src)
126{ 135{
127 register int r0 asm("0") = 0; 136 register int r0 asm("0") = 0;
@@ -137,7 +146,9 @@ static inline char *strcat(char *dst, const char *src)
137 : "d" (r0), "0" (0) : "cc", "memory" ); 146 : "d" (r0), "0" (0) : "cc", "memory" );
138 return ret; 147 return ret;
139} 148}
149#endif
140 150
151#ifdef __HAVE_ARCH_STRCPY
141static inline char *strcpy(char *dst, const char *src) 152static inline char *strcpy(char *dst, const char *src)
142{ 153{
143 register int r0 asm("0") = 0; 154 register int r0 asm("0") = 0;
@@ -150,7 +161,9 @@ static inline char *strcpy(char *dst, const char *src)
150 : "cc", "memory"); 161 : "cc", "memory");
151 return ret; 162 return ret;
152} 163}
164#endif
153 165
166#ifdef __HAVE_ARCH_STRLEN
154static inline size_t strlen(const char *s) 167static inline size_t strlen(const char *s)
155{ 168{
156 register unsigned long r0 asm("0") = 0; 169 register unsigned long r0 asm("0") = 0;
@@ -162,7 +175,9 @@ static inline size_t strlen(const char *s)
162 : "+d" (r0), "+a" (tmp) : : "cc", "memory"); 175 : "+d" (r0), "+a" (tmp) : : "cc", "memory");
163 return r0 - (unsigned long) s; 176 return r0 - (unsigned long) s;
164} 177}
178#endif
165 179
180#ifdef __HAVE_ARCH_STRNLEN
166static inline size_t strnlen(const char * s, size_t n) 181static inline size_t strnlen(const char * s, size_t n)
167{ 182{
168 register int r0 asm("0") = 0; 183 register int r0 asm("0") = 0;
@@ -175,6 +190,7 @@ static inline size_t strnlen(const char * s, size_t n)
175 : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); 190 : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory");
176 return end - s; 191 return end - s;
177} 192}
193#endif
178#else /* IN_ARCH_STRING_C */ 194#else /* IN_ARCH_STRING_C */
179void *memchr(const void * s, int c, size_t n); 195void *memchr(const void * s, int c, size_t n);
180void *memscan(void *s, int c, size_t n); 196void *memscan(void *s, int c, size_t n);
diff --git a/arch/s390/lib/string.c b/arch/s390/lib/string.c
index a10e11f7a5f7..0e30e6e43b0c 100644
--- a/arch/s390/lib/string.c
+++ b/arch/s390/lib/string.c
@@ -43,11 +43,13 @@ static inline char *__strnend(const char *s, size_t n)
43 * 43 *
44 * returns the length of @s 44 * returns the length of @s
45 */ 45 */
46#ifdef __HAVE_ARCH_STRLEN
46size_t strlen(const char *s) 47size_t strlen(const char *s)
47{ 48{
48 return __strend(s) - s; 49 return __strend(s) - s;
49} 50}
50EXPORT_SYMBOL(strlen); 51EXPORT_SYMBOL(strlen);
52#endif
51 53
52/** 54/**
53 * strnlen - Find the length of a length-limited string 55 * strnlen - Find the length of a length-limited string
@@ -56,11 +58,13 @@ EXPORT_SYMBOL(strlen);
56 * 58 *
57 * returns the minimum of the length of @s and @n 59 * returns the minimum of the length of @s and @n
58 */ 60 */
61#ifdef __HAVE_ARCH_STRNLEN
59size_t strnlen(const char *s, size_t n) 62size_t strnlen(const char *s, size_t n)
60{ 63{
61 return __strnend(s, n) - s; 64 return __strnend(s, n) - s;
62} 65}
63EXPORT_SYMBOL(strnlen); 66EXPORT_SYMBOL(strnlen);
67#endif
64 68
65/** 69/**
66 * strcpy - Copy a %NUL terminated string 70 * strcpy - Copy a %NUL terminated string
@@ -69,6 +73,7 @@ EXPORT_SYMBOL(strnlen);
69 * 73 *
70 * returns a pointer to @dest 74 * returns a pointer to @dest
71 */ 75 */
76#ifdef __HAVE_ARCH_STRCPY
72char *strcpy(char *dest, const char *src) 77char *strcpy(char *dest, const char *src)
73{ 78{
74 register int r0 asm("0") = 0; 79 register int r0 asm("0") = 0;
@@ -81,6 +86,7 @@ char *strcpy(char *dest, const char *src)
81 return ret; 86 return ret;
82} 87}
83EXPORT_SYMBOL(strcpy); 88EXPORT_SYMBOL(strcpy);
89#endif
84 90
85/** 91/**
86 * strlcpy - Copy a %NUL terminated string into a sized buffer 92 * strlcpy - Copy a %NUL terminated string into a sized buffer
@@ -93,6 +99,7 @@ EXPORT_SYMBOL(strcpy);
93 * of course, the buffer size is zero). It does not pad 99 * of course, the buffer size is zero). It does not pad
94 * out the result like strncpy() does. 100 * out the result like strncpy() does.
95 */ 101 */
102#ifdef __HAVE_ARCH_STRLCPY
96size_t strlcpy(char *dest, const char *src, size_t size) 103size_t strlcpy(char *dest, const char *src, size_t size)
97{ 104{
98 size_t ret = __strend(src) - src; 105 size_t ret = __strend(src) - src;
@@ -105,6 +112,7 @@ size_t strlcpy(char *dest, const char *src, size_t size)
105 return ret; 112 return ret;
106} 113}
107EXPORT_SYMBOL(strlcpy); 114EXPORT_SYMBOL(strlcpy);
115#endif
108 116
109/** 117/**
110 * strncpy - Copy a length-limited, %NUL-terminated string 118 * strncpy - Copy a length-limited, %NUL-terminated string
@@ -115,6 +123,7 @@ EXPORT_SYMBOL(strlcpy);
115 * The result is not %NUL-terminated if the source exceeds 123 * The result is not %NUL-terminated if the source exceeds
116 * @n bytes. 124 * @n bytes.
117 */ 125 */
126#ifdef __HAVE_ARCH_STRNCPY
118char *strncpy(char *dest, const char *src, size_t n) 127char *strncpy(char *dest, const char *src, size_t n)
119{ 128{
120 size_t len = __strnend(src, n) - src; 129 size_t len = __strnend(src, n) - src;
@@ -123,6 +132,7 @@ char *strncpy(char *dest, const char *src, size_t n)
123 return dest; 132 return dest;
124} 133}
125EXPORT_SYMBOL(strncpy); 134EXPORT_SYMBOL(strncpy);
135#endif
126 136
127/** 137/**
128 * strcat - Append one %NUL-terminated string to another 138 * strcat - Append one %NUL-terminated string to another
@@ -131,6 +141,7 @@ EXPORT_SYMBOL(strncpy);
131 * 141 *
132 * returns a pointer to @dest 142 * returns a pointer to @dest
133 */ 143 */
144#ifdef __HAVE_ARCH_STRCAT
134char *strcat(char *dest, const char *src) 145char *strcat(char *dest, const char *src)
135{ 146{
136 register int r0 asm("0") = 0; 147 register int r0 asm("0") = 0;
@@ -146,6 +157,7 @@ char *strcat(char *dest, const char *src)
146 return ret; 157 return ret;
147} 158}
148EXPORT_SYMBOL(strcat); 159EXPORT_SYMBOL(strcat);
160#endif
149 161
150/** 162/**
151 * strlcat - Append a length-limited, %NUL-terminated string to another 163 * strlcat - Append a length-limited, %NUL-terminated string to another
@@ -153,6 +165,7 @@ EXPORT_SYMBOL(strcat);
153 * @src: The string to append to it 165 * @src: The string to append to it
154 * @n: The size of the destination buffer. 166 * @n: The size of the destination buffer.
155 */ 167 */
168#ifdef __HAVE_ARCH_STRLCAT
156size_t strlcat(char *dest, const char *src, size_t n) 169size_t strlcat(char *dest, const char *src, size_t n)
157{ 170{
158 size_t dsize = __strend(dest) - dest; 171 size_t dsize = __strend(dest) - dest;
@@ -170,6 +183,7 @@ size_t strlcat(char *dest, const char *src, size_t n)
170 return res; 183 return res;
171} 184}
172EXPORT_SYMBOL(strlcat); 185EXPORT_SYMBOL(strlcat);
186#endif
173 187
174/** 188/**
175 * strncat - Append a length-limited, %NUL-terminated string to another 189 * strncat - Append a length-limited, %NUL-terminated string to another
@@ -182,6 +196,7 @@ EXPORT_SYMBOL(strlcat);
182 * Note that in contrast to strncpy, strncat ensures the result is 196 * Note that in contrast to strncpy, strncat ensures the result is
183 * terminated. 197 * terminated.
184 */ 198 */
199#ifdef __HAVE_ARCH_STRNCAT
185char *strncat(char *dest, const char *src, size_t n) 200char *strncat(char *dest, const char *src, size_t n)
186{ 201{
187 size_t len = __strnend(src, n) - src; 202 size_t len = __strnend(src, n) - src;
@@ -192,6 +207,7 @@ char *strncat(char *dest, const char *src, size_t n)
192 return dest; 207 return dest;
193} 208}
194EXPORT_SYMBOL(strncat); 209EXPORT_SYMBOL(strncat);
210#endif
195 211
196/** 212/**
197 * strcmp - Compare two strings 213 * strcmp - Compare two strings
@@ -202,6 +218,7 @@ EXPORT_SYMBOL(strncat);
202 * < 0 if @s1 is less than @s2 218 * < 0 if @s1 is less than @s2
203 * > 0 if @s1 is greater than @s2 219 * > 0 if @s1 is greater than @s2
204 */ 220 */
221#ifdef __HAVE_ARCH_STRCMP
205int strcmp(const char *s1, const char *s2) 222int strcmp(const char *s1, const char *s2)
206{ 223{
207 register int r0 asm("0") = 0; 224 register int r0 asm("0") = 0;
@@ -219,12 +236,14 @@ int strcmp(const char *s1, const char *s2)
219 return ret; 236 return ret;
220} 237}
221EXPORT_SYMBOL(strcmp); 238EXPORT_SYMBOL(strcmp);
239#endif
222 240
223/** 241/**
224 * strrchr - Find the last occurrence of a character in a string 242 * strrchr - Find the last occurrence of a character in a string
225 * @s: The string to be searched 243 * @s: The string to be searched
226 * @c: The character to search for 244 * @c: The character to search for
227 */ 245 */
246#ifdef __HAVE_ARCH_STRRCHR
228char *strrchr(const char *s, int c) 247char *strrchr(const char *s, int c)
229{ 248{
230 size_t len = __strend(s) - s; 249 size_t len = __strend(s) - s;
@@ -237,6 +256,7 @@ char *strrchr(const char *s, int c)
237 return NULL; 256 return NULL;
238} 257}
239EXPORT_SYMBOL(strrchr); 258EXPORT_SYMBOL(strrchr);
259#endif
240 260
241static inline int clcle(const char *s1, unsigned long l1, 261static inline int clcle(const char *s1, unsigned long l1,
242 const char *s2, unsigned long l2) 262 const char *s2, unsigned long l2)
@@ -261,6 +281,7 @@ static inline int clcle(const char *s1, unsigned long l1,
261 * @s1: The string to be searched 281 * @s1: The string to be searched
262 * @s2: The string to search for 282 * @s2: The string to search for
263 */ 283 */
284#ifdef __HAVE_ARCH_STRSTR
264char *strstr(const char *s1, const char *s2) 285char *strstr(const char *s1, const char *s2)
265{ 286{
266 int l1, l2; 287 int l1, l2;
@@ -280,6 +301,7 @@ char *strstr(const char *s1, const char *s2)
280 return NULL; 301 return NULL;
281} 302}
282EXPORT_SYMBOL(strstr); 303EXPORT_SYMBOL(strstr);
304#endif
283 305
284/** 306/**
285 * memchr - Find a character in an area of memory. 307 * memchr - Find a character in an area of memory.
@@ -290,6 +312,7 @@ EXPORT_SYMBOL(strstr);
290 * returns the address of the first occurrence of @c, or %NULL 312 * returns the address of the first occurrence of @c, or %NULL
291 * if @c is not found 313 * if @c is not found
292 */ 314 */
315#ifdef __HAVE_ARCH_MEMCHR
293void *memchr(const void *s, int c, size_t n) 316void *memchr(const void *s, int c, size_t n)
294{ 317{
295 register int r0 asm("0") = (char) c; 318 register int r0 asm("0") = (char) c;
@@ -304,6 +327,7 @@ void *memchr(const void *s, int c, size_t n)
304 return (void *) ret; 327 return (void *) ret;
305} 328}
306EXPORT_SYMBOL(memchr); 329EXPORT_SYMBOL(memchr);
330#endif
307 331
308/** 332/**
309 * memcmp - Compare two areas of memory 333 * memcmp - Compare two areas of memory
@@ -311,6 +335,7 @@ EXPORT_SYMBOL(memchr);
311 * @s2: Another area of memory 335 * @s2: Another area of memory
312 * @count: The size of the area. 336 * @count: The size of the area.
313 */ 337 */
338#ifdef __HAVE_ARCH_MEMCMP
314int memcmp(const void *s1, const void *s2, size_t n) 339int memcmp(const void *s1, const void *s2, size_t n)
315{ 340{
316 int ret; 341 int ret;
@@ -321,6 +346,7 @@ int memcmp(const void *s1, const void *s2, size_t n)
321 return ret; 346 return ret;
322} 347}
323EXPORT_SYMBOL(memcmp); 348EXPORT_SYMBOL(memcmp);
349#endif
324 350
325/** 351/**
326 * memscan - Find a character in an area of memory. 352 * memscan - Find a character in an area of memory.
@@ -331,6 +357,7 @@ EXPORT_SYMBOL(memcmp);
331 * returns the address of the first occurrence of @c, or 1 byte past 357 * returns the address of the first occurrence of @c, or 1 byte past
332 * the area if @c is not found 358 * the area if @c is not found
333 */ 359 */
360#ifdef __HAVE_ARCH_MEMSCAN
334void *memscan(void *s, int c, size_t n) 361void *memscan(void *s, int c, size_t n)
335{ 362{
336 register int r0 asm("0") = (char) c; 363 register int r0 asm("0") = (char) c;
@@ -342,3 +369,4 @@ void *memscan(void *s, int c, size_t n)
342 return (void *) ret; 369 return (void *) ret;
343} 370}
344EXPORT_SYMBOL(memscan); 371EXPORT_SYMBOL(memscan);
372#endif