| .. | .. |
|---|
| 12 | 12 | #include <linux/types.h> |
|---|
| 13 | 13 | #endif |
|---|
| 14 | 14 | |
|---|
| 15 | | -#define __HAVE_ARCH_MEMCHR /* inline & arch function */ |
|---|
| 16 | | -#define __HAVE_ARCH_MEMCMP /* arch function */ |
|---|
| 17 | 15 | #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ |
|---|
| 18 | 16 | #define __HAVE_ARCH_MEMMOVE /* gcc builtin & arch function */ |
|---|
| 19 | | -#define __HAVE_ARCH_MEMSCAN /* inline & arch function */ |
|---|
| 20 | 17 | #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ |
|---|
| 21 | 18 | #define __HAVE_ARCH_MEMSET16 /* arch function */ |
|---|
| 22 | 19 | #define __HAVE_ARCH_MEMSET32 /* arch function */ |
|---|
| 23 | 20 | #define __HAVE_ARCH_MEMSET64 /* arch function */ |
|---|
| 21 | + |
|---|
| 22 | +void *memcpy(void *dest, const void *src, size_t n); |
|---|
| 23 | +void *memset(void *s, int c, size_t n); |
|---|
| 24 | +void *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 | 30 | #define __HAVE_ARCH_STRCAT /* inline & arch function */ |
|---|
| 25 | 31 | #define __HAVE_ARCH_STRCMP /* arch function */ |
|---|
| 26 | 32 | #define __HAVE_ARCH_STRCPY /* inline & arch function */ |
|---|
| .. | .. |
|---|
| 35 | 41 | |
|---|
| 36 | 42 | /* Prototypes for non-inlined arch strings functions. */ |
|---|
| 37 | 43 | int memcmp(const void *s1, const void *s2, size_t n); |
|---|
| 38 | | -void *memcpy(void *dest, const void *src, size_t n); |
|---|
| 39 | | -void *memset(void *s, int c, size_t n); |
|---|
| 40 | | -void *memmove(void *dest, const void *src, size_t n); |
|---|
| 41 | 44 | int strcmp(const char *s1, const char *s2); |
|---|
| 42 | 45 | size_t strlcat(char *dest, const char *src, size_t n); |
|---|
| 43 | 46 | size_t strlcpy(char *dest, const char *src, size_t size); |
|---|
| .. | .. |
|---|
| 45 | 48 | char *strncpy(char *dest, const char *src, size_t n); |
|---|
| 46 | 49 | char *strrchr(const char *s, int c); |
|---|
| 47 | 50 | char *strstr(const char *s1, const char *s2); |
|---|
| 51 | +#endif /* !CONFIG_KASAN */ |
|---|
| 48 | 52 | |
|---|
| 49 | 53 | #undef __HAVE_ARCH_STRCHR |
|---|
| 50 | 54 | #undef __HAVE_ARCH_STRNCHR |
|---|
| .. | .. |
|---|
| 52 | 56 | #undef __HAVE_ARCH_STRPBRK |
|---|
| 53 | 57 | #undef __HAVE_ARCH_STRSEP |
|---|
| 54 | 58 | #undef __HAVE_ARCH_STRSPN |
|---|
| 59 | + |
|---|
| 60 | +#if defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) |
|---|
| 61 | + |
|---|
| 62 | +extern void *__memcpy(void *dest, const void *src, size_t n); |
|---|
| 63 | +extern void *__memset(void *s, int c, size_t n); |
|---|
| 64 | +extern void *__memmove(void *dest, const void *src, size_t n); |
|---|
| 65 | + |
|---|
| 66 | +/* |
|---|
| 67 | + * For files that are not instrumented (e.g. mm/slub.c) we |
|---|
| 68 | + * should use not instrumented version of mem* functions. |
|---|
| 69 | + */ |
|---|
| 70 | + |
|---|
| 71 | +#define memcpy(dst, src, len) __memcpy(dst, src, len) |
|---|
| 72 | +#define memmove(dst, src, len) __memmove(dst, src, len) |
|---|
| 73 | +#define memset(s, c, n) __memset(s, c, n) |
|---|
| 74 | +#define strlen(s) __strlen(s) |
|---|
| 75 | + |
|---|
| 76 | +#define __no_sanitize_prefix_strfunc(x) __##x |
|---|
| 77 | + |
|---|
| 78 | +#ifndef __NO_FORTIFY |
|---|
| 79 | +#define __NO_FORTIFY /* FORTIFY_SOURCE uses __builtin_memcpy, etc. */ |
|---|
| 80 | +#endif |
|---|
| 81 | + |
|---|
| 82 | +#else |
|---|
| 83 | +#define __no_sanitize_prefix_strfunc(x) x |
|---|
| 84 | +#endif /* defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__) */ |
|---|
| 55 | 85 | |
|---|
| 56 | 86 | void *__memset16(uint16_t *s, uint16_t v, size_t count); |
|---|
| 57 | 87 | void *__memset32(uint32_t *s, uint32_t v, size_t count); |
|---|
| .. | .. |
|---|
| 74 | 104 | |
|---|
| 75 | 105 | #if !defined(IN_ARCH_STRING_C) && (!defined(CONFIG_FORTIFY_SOURCE) || defined(__NO_FORTIFY)) |
|---|
| 76 | 106 | |
|---|
| 107 | +#ifdef __HAVE_ARCH_MEMCHR |
|---|
| 77 | 108 | static inline void *memchr(const void * s, int c, size_t n) |
|---|
| 78 | 109 | { |
|---|
| 79 | 110 | register int r0 asm("0") = (char) c; |
|---|
| .. | .. |
|---|
| 88 | 119 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); |
|---|
| 89 | 120 | return (void *) ret; |
|---|
| 90 | 121 | } |
|---|
| 122 | +#endif |
|---|
| 91 | 123 | |
|---|
| 124 | +#ifdef __HAVE_ARCH_MEMSCAN |
|---|
| 92 | 125 | static inline void *memscan(void *s, int c, size_t n) |
|---|
| 93 | 126 | { |
|---|
| 94 | 127 | register int r0 asm("0") = (char) c; |
|---|
| .. | .. |
|---|
| 100 | 133 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc", "memory"); |
|---|
| 101 | 134 | return (void *) ret; |
|---|
| 102 | 135 | } |
|---|
| 136 | +#endif |
|---|
| 103 | 137 | |
|---|
| 138 | +#ifdef __HAVE_ARCH_STRCAT |
|---|
| 104 | 139 | static inline char *strcat(char *dst, const char *src) |
|---|
| 105 | 140 | { |
|---|
| 106 | 141 | register int r0 asm("0") = 0; |
|---|
| .. | .. |
|---|
| 116 | 151 | : "d" (r0), "0" (0) : "cc", "memory" ); |
|---|
| 117 | 152 | return ret; |
|---|
| 118 | 153 | } |
|---|
| 154 | +#endif |
|---|
| 119 | 155 | |
|---|
| 156 | +#ifdef __HAVE_ARCH_STRCPY |
|---|
| 120 | 157 | static inline char *strcpy(char *dst, const char *src) |
|---|
| 121 | 158 | { |
|---|
| 122 | 159 | register int r0 asm("0") = 0; |
|---|
| .. | .. |
|---|
| 129 | 166 | : "cc", "memory"); |
|---|
| 130 | 167 | return ret; |
|---|
| 131 | 168 | } |
|---|
| 169 | +#endif |
|---|
| 132 | 170 | |
|---|
| 133 | | -static inline size_t strlen(const char *s) |
|---|
| 171 | +#if defined(__HAVE_ARCH_STRLEN) || (defined(CONFIG_KASAN) && !defined(__SANITIZE_ADDRESS__)) |
|---|
| 172 | +static inline size_t __no_sanitize_prefix_strfunc(strlen)(const char *s) |
|---|
| 134 | 173 | { |
|---|
| 135 | 174 | register unsigned long r0 asm("0") = 0; |
|---|
| 136 | 175 | const char *tmp = s; |
|---|
| .. | .. |
|---|
| 141 | 180 | : "+d" (r0), "+a" (tmp) : : "cc", "memory"); |
|---|
| 142 | 181 | return r0 - (unsigned long) s; |
|---|
| 143 | 182 | } |
|---|
| 183 | +#endif |
|---|
| 144 | 184 | |
|---|
| 185 | +#ifdef __HAVE_ARCH_STRNLEN |
|---|
| 145 | 186 | static inline size_t strnlen(const char * s, size_t n) |
|---|
| 146 | 187 | { |
|---|
| 147 | 188 | register int r0 asm("0") = 0; |
|---|
| .. | .. |
|---|
| 154 | 195 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc", "memory"); |
|---|
| 155 | 196 | return end - s; |
|---|
| 156 | 197 | } |
|---|
| 198 | +#endif |
|---|
| 157 | 199 | #else /* IN_ARCH_STRING_C */ |
|---|
| 158 | 200 | void *memchr(const void * s, int c, size_t n); |
|---|
| 159 | 201 | void *memscan(void *s, int c, size_t n); |
|---|