| 1 |
|
| 2 | #ifndef _LINUX_STRING_H_
|
| 3 | #define _LINUX_STRING_H_
|
| 4 |
|
| 5 |
|
| 6 | #include <linux/compiler.h>
|
| 7 | #include <linux/types.h>
|
| 8 | #include <linux/stddef.h>
|
| 9 | #include <stdarg.h>
|
| 10 | #include <uapi/linux/string.h>
|
| 11 |
|
| 12 | extern char *strndup_user(const char __user *, long);
|
| 13 | extern void *memdup_user(const void __user *, size_t);
|
| 14 | extern void *vmemdup_user(const void __user *, size_t);
|
| 15 | extern void *memdup_user_nul(const void __user *, size_t);
|
| 16 |
|
| 17 | |
| 18 | * Include machine specific inline routines
|
| 19 |
|
| 20 | #include <asm/string.h>
|
| 21 |
|
| 22 | #ifndef __HAVE_ARCH_STRCPY
|
| 23 | extern char * strcpy(char *,const char *);
|
| 24 | #endif
|
| 25 | #ifndef __HAVE_ARCH_STRNCPY
|
| 26 | extern char * strncpy(char *,const char *, __kernel_size_t);
|
| 27 | #endif
|
| 28 | #ifndef __HAVE_ARCH_STRLCPY
|
| 29 | size_t strlcpy(char *, const char *, size_t);
|
| 30 | #endif
|
| 31 | #ifndef __HAVE_ARCH_STRSCPY
|
| 32 | ssize_t strscpy(char *, const char *, size_t);
|
| 33 | #endif
|
| 34 | #ifndef __HAVE_ARCH_STRCAT
|
| 35 | extern char * strcat(char *, const char *);
|
| 36 | #endif
|
| 37 | #ifndef __HAVE_ARCH_STRNCAT
|
| 38 | extern char * strncat(char *, const char *, __kernel_size_t);
|
| 39 | #endif
|
| 40 | #ifndef __HAVE_ARCH_STRLCAT
|
| 41 | extern size_t strlcat(char *, const char *, __kernel_size_t);
|
| 42 | #endif
|
| 43 | #ifndef __HAVE_ARCH_STRCMP
|
| 44 | extern int strcmp(const char *,const char *);
|
| 45 | #endif
|
| 46 | #ifndef __HAVE_ARCH_STRNCMP
|
| 47 | extern int strncmp(const char *,const char *,__kernel_size_t);
|
| 48 | #endif
|
| 49 | #ifndef __HAVE_ARCH_STRCASECMP
|
| 50 | extern int strcasecmp(const char *s1, const char *s2);
|
| 51 | #endif
|
| 52 | #ifndef __HAVE_ARCH_STRNCASECMP
|
| 53 | extern int strncasecmp(const char *s1, const char *s2, size_t n);
|
| 54 | #endif
|
| 55 | #ifndef __HAVE_ARCH_STRCHR
|
| 56 | extern char * strchr(const char *,int);
|
| 57 | #endif
|
| 58 | #ifndef __HAVE_ARCH_STRCHRNUL
|
| 59 | extern char * strchrnul(const char *,int);
|
| 60 | #endif
|
| 61 | #ifndef __HAVE_ARCH_STRNCHR
|
| 62 | extern char * strnchr(const char *, size_t, int);
|
| 63 | #endif
|
| 64 | #ifndef __HAVE_ARCH_STRRCHR
|
| 65 | extern char * strrchr(const char *,int);
|
| 66 | #endif
|
| 67 | extern char * __must_check skip_spaces(const char *);
|
| 68 |
|
| 69 | extern char *strim(char *);
|
| 70 |
|
| 71 | static inline __must_check char *strstrip(char *str)
|
| 72 | {
|
| 73 | return strim(str);
|
| 74 | }
|
| 75 |
|
| 76 | #ifndef __HAVE_ARCH_STRSTR
|
| 77 | extern char * strstr(const char *, const char *);
|
| 78 | #endif
|
| 79 | #ifndef __HAVE_ARCH_STRNSTR
|
| 80 | extern char * strnstr(const char *, const char *, size_t);
|
| 81 | #endif
|
| 82 | #ifndef __HAVE_ARCH_STRLEN
|
| 83 | extern __kernel_size_t strlen(const char *);
|
| 84 | #endif
|
| 85 | #ifndef __HAVE_ARCH_STRNLEN
|
| 86 | extern __kernel_size_t strnlen(const char *,__kernel_size_t);
|
| 87 | #endif
|
| 88 | #ifndef __HAVE_ARCH_STRPBRK
|
| 89 | extern char * strpbrk(const char *,const char *);
|
| 90 | #endif
|
| 91 | #ifndef __HAVE_ARCH_STRSEP
|
| 92 | extern char * strsep(char **,const char *);
|
| 93 | #endif
|
| 94 | #ifndef __HAVE_ARCH_STRSPN
|
| 95 | extern __kernel_size_t strspn(const char *,const char *);
|
| 96 | #endif
|
| 97 | #ifndef __HAVE_ARCH_STRCSPN
|
| 98 | extern __kernel_size_t strcspn(const char *,const char *);
|
| 99 | #endif
|
| 100 |
|
| 101 | #ifndef __HAVE_ARCH_MEMSET
|
| 102 | extern void * memset(void *,int,__kernel_size_t);
|
| 103 | #endif
|
| 104 |
|
| 105 | #ifndef __HAVE_ARCH_MEMSET16
|
| 106 | extern void *memset16(uint16_t *, uint16_t, __kernel_size_t);
|
| 107 | #endif
|
| 108 |
|
| 109 | #ifndef __HAVE_ARCH_MEMSET32
|
| 110 | extern void *memset32(uint32_t *, uint32_t, __kernel_size_t);
|
| 111 | #endif
|
| 112 |
|
| 113 | #ifndef __HAVE_ARCH_MEMSET64
|
| 114 | extern void *memset64(uint64_t *, uint64_t, __kernel_size_t);
|
| 115 | #endif
|
| 116 |
|
| 117 | static inline void *memset_l(unsigned long *p, unsigned long v,
|
| 118 | __kernel_size_t n)
|
| 119 | {
|
| 120 | if (BITS_PER_LONG == 32)
|
| 121 | return memset32((uint32_t *)p, v, n);
|
| 122 | else
|
| 123 | return memset64((uint64_t *)p, v, n);
|
| 124 | }
|
| 125 |
|
| 126 | static inline void *memset_p(void **p, void *v, __kernel_size_t n)
|
| 127 | {
|
| 128 | if (BITS_PER_LONG == 32)
|
| 129 | return memset32((uint32_t *)p, (uintptr_t)v, n);
|
| 130 | else
|
| 131 | return memset64((uint64_t *)p, (uintptr_t)v, n);
|
| 132 | }
|
| 133 |
|
| 134 | #ifndef __HAVE_ARCH_MEMCPY
|
| 135 | extern void * memcpy(void *,const void *,__kernel_size_t);
|
| 136 | #endif
|
| 137 | #ifndef __HAVE_ARCH_MEMMOVE
|
| 138 | extern void * memmove(void *,const void *,__kernel_size_t);
|
| 139 | #endif
|
| 140 | #ifndef __HAVE_ARCH_MEMSCAN
|
| 141 | extern void * memscan(void *,int,__kernel_size_t);
|
| 142 | #endif
|
| 143 | #ifndef __HAVE_ARCH_MEMCMP
|
| 144 | extern int memcmp(const void *,const void *,__kernel_size_t);
|
| 145 | #endif
|
| 146 | #ifndef __HAVE_ARCH_MEMCHR
|
| 147 | extern void * memchr(const void *,int,__kernel_size_t);
|
| 148 | #endif
|
| 149 | #ifndef __HAVE_ARCH_MEMCPY_MCSAFE
|
| 150 | static inline __must_check unsigned long memcpy_mcsafe(void *dst,
|
| 151 | const void *src, size_t cnt)
|
| 152 | {
|
| 153 | memcpy(dst, src, cnt);
|
| 154 | return 0;
|
| 155 | }
|
| 156 | #endif
|
| 157 | #ifndef __HAVE_ARCH_MEMCPY_FLUSHCACHE
|
| 158 | static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
|
| 159 | {
|
| 160 | memcpy(dst, src, cnt);
|
| 161 | }
|
| 162 | #endif
|
| 163 | void *memchr_inv(const void *s, int c, size_t n);
|
| 164 | char *strreplace(char *s, char old, char new);
|
| 165 |
|
| 166 | extern void kfree_const(const void *x);
|
| 167 |
|
| 168 | extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
|
| 169 | extern const char *kstrdup_const(const char *s, gfp_t gfp);
|
| 170 | extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
|
| 171 | extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
|
| 172 | extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
|
| 173 |
|
| 174 | extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
|
| 175 | extern void argv_free(char **argv);
|
| 176 |
|
| 177 | extern bool sysfs_streq(const char *s1, const char *s2);
|
| 178 | extern int kstrtobool(const char *s, bool *res);
|
| 179 | static inline int strtobool(const char *s, bool *res)
|
| 180 | {
|
| 181 | return kstrtobool(s, res);
|
| 182 | }
|
| 183 |
|
| 184 | int match_string(const char * const *array, size_t n, const char *string);
|
| 185 | int __sysfs_match_string(const char * const *array, size_t n, const char *s);
|
| 186 |
|
| 187 | |
| 188 | * sysfs_match_string - matches given string in an array
|
| 189 | * @_a: array of strings
|
| 190 | * @_s: string to match with
|
| 191 | *
|
| 192 | * Helper for __sysfs_match_string(). Calculates the size of @a automatically.
|
| 193 |
|
| 194 | #define sysfs_match_string(_a, _s) __sysfs_match_string(_a, ARRAY_SIZE(_a), _s)
|
| 195 |
|
| 196 | #ifdef CONFIG_BINARY_PRINTF
|
| 197 | int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
|
| 198 | int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
|
| 199 | int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
|
| 200 | #endif
|
| 201 |
|
| 202 | extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
|
| 203 | const void *from, size_t available);
|
| 204 |
|
| 205 | |
| 206 | * strstarts - does @str start with @prefix?
|
| 207 | * @str: string to examine
|
| 208 | * @prefix: prefix to look for.
|
| 209 |
|
| 210 | static inline bool strstarts(const char *str, const char *prefix)
|
| 211 | {
|
| 212 | return strncmp(str, prefix, strlen(prefix)) == 0;
|
| 213 | }
|
| 214 |
|
| 215 | size_t memweight(const void *ptr, size_t bytes);
|
| 216 | void memzero_explicit(void *s, size_t count);
|
| 217 |
|
| 218 | |
| 219 | * kbasename - return the last part of a pathname.
|
| 220 | *
|
| 221 | * @path: path to extract the filename from.
|
| 222 |
|
| 223 | static inline const char *kbasename(const char *path)
|
| 224 | {
|
| 225 | const char *tail = strrchr(path, '/');
|
| 226 | return tail ? tail + 1 : path;
|
| 227 | }
|
| 228 |
|
| 229 | #define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline))
|
| 230 | #define __RENAME(x) __asm__(#x)
|
| 231 |
|
| 232 | void fortify_panic(const char *name) __noreturn __cold;
|
| 233 | void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter");
|
| 234 | void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter");
|
| 235 | void __read_overflow3(void) __compiletime_error("detected read beyond size of object passed as 3rd parameter");
|
| 236 | void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
|
| 237 |
|
| 238 | #if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
|
| 239 | __FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
|
| 240 | {
|
| 241 | size_t p_size = __builtin_object_size(p, 0);
|
| 242 | if (__builtin_constant_p(size) && p_size < size)
|
| 243 | __write_overflow();
|
| 244 | if (p_size < size)
|
| 245 | fortify_panic(__func__);
|
| 246 | return __builtin_strncpy(p, q, size);
|
| 247 | }
|
| 248 |
|
| 249 | __FORTIFY_INLINE char *strcat(char *p, const char *q)
|
| 250 | {
|
| 251 | size_t p_size = __builtin_object_size(p, 0);
|
| 252 | if (p_size == (size_t)-1)
|
| 253 | return __builtin_strcat(p, q);
|
| 254 | if (strlcat(p, q, p_size) >= p_size)
|
| 255 | fortify_panic(__func__);
|
| 256 | return p;
|
| 257 | }
|
| 258 |
|
| 259 | __FORTIFY_INLINE __kernel_size_t strlen(const char *p)
|
| 260 | {
|
| 261 | __kernel_size_t ret;
|
| 262 | size_t p_size = __builtin_object_size(p, 0);
|
| 263 |
|
| 264 |
|
| 265 | if (p_size == (size_t)-1 ||
|
| 266 | (__builtin_constant_p(p[p_size - 1]) && p[p_size - 1] == '\0'))
|
| 267 | return __builtin_strlen(p);
|
| 268 | ret = strnlen(p, p_size);
|
| 269 | if (p_size <= ret)
|
| 270 | fortify_panic(__func__);
|
| 271 | return ret;
|
| 272 | }
|
| 273 |
|
| 274 | extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
|
| 275 | __FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
|
| 276 | {
|
| 277 | size_t p_size = __builtin_object_size(p, 0);
|
| 278 | __kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
|
| 279 | if (p_size <= ret && maxlen != ret)
|
| 280 | fortify_panic(__func__);
|
| 281 | return ret;
|
| 282 | }
|
| 283 |
|
| 284 |
|
| 285 | extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
|
| 286 | __FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
|
| 287 | {
|
| 288 | size_t ret;
|
| 289 | size_t p_size = __builtin_object_size(p, 0);
|
| 290 | size_t q_size = __builtin_object_size(q, 0);
|
| 291 | if (p_size == (size_t)-1 && q_size == (size_t)-1)
|
| 292 | return __real_strlcpy(p, q, size);
|
| 293 | ret = strlen(q);
|
| 294 | if (size) {
|
| 295 | size_t len = (ret >= size) ? size - 1 : ret;
|
| 296 | if (__builtin_constant_p(len) && len >= p_size)
|
| 297 | __write_overflow();
|
| 298 | if (len >= p_size)
|
| 299 | fortify_panic(__func__);
|
| 300 | __builtin_memcpy(p, q, len);
|
| 301 | p[len] = '\0';
|
| 302 | }
|
| 303 | return ret;
|
| 304 | }
|
| 305 |
|
| 306 |
|
| 307 | __FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
|
| 308 | {
|
| 309 | size_t p_len, copy_len;
|
| 310 | size_t p_size = __builtin_object_size(p, 0);
|
| 311 | size_t q_size = __builtin_object_size(q, 0);
|
| 312 | if (p_size == (size_t)-1 && q_size == (size_t)-1)
|
| 313 | return __builtin_strncat(p, q, count);
|
| 314 | p_len = strlen(p);
|
| 315 | copy_len = strnlen(q, count);
|
| 316 | if (p_size < p_len + copy_len + 1)
|
| 317 | fortify_panic(__func__);
|
| 318 | __builtin_memcpy(p + p_len, q, copy_len);
|
| 319 | p[p_len + copy_len] = '\0';
|
| 320 | return p;
|
| 321 | }
|
| 322 |
|
| 323 | __FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size)
|
| 324 | {
|
| 325 | size_t p_size = __builtin_object_size(p, 0);
|
| 326 | if (__builtin_constant_p(size) && p_size < size)
|
| 327 | __write_overflow();
|
| 328 | if (p_size < size)
|
| 329 | fortify_panic(__func__);
|
| 330 | return __builtin_memset(p, c, size);
|
| 331 | }
|
| 332 |
|
| 333 | __FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size)
|
| 334 | {
|
| 335 | size_t p_size = __builtin_object_size(p, 0);
|
| 336 | size_t q_size = __builtin_object_size(q, 0);
|
| 337 | if (__builtin_constant_p(size)) {
|
| 338 | if (p_size < size)
|
| 339 | __write_overflow();
|
| 340 | if (q_size < size)
|
| 341 | __read_overflow2();
|
| 342 | }
|
| 343 | if (p_size < size || q_size < size)
|
| 344 | fortify_panic(__func__);
|
| 345 | return __builtin_memcpy(p, q, size);
|
| 346 | }
|
| 347 |
|
| 348 | __FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
|
| 349 | {
|
| 350 | size_t p_size = __builtin_object_size(p, 0);
|
| 351 | size_t q_size = __builtin_object_size(q, 0);
|
| 352 | if (__builtin_constant_p(size)) {
|
| 353 | if (p_size < size)
|
| 354 | __write_overflow();
|
| 355 | if (q_size < size)
|
| 356 | __read_overflow2();
|
| 357 | }
|
| 358 | if (p_size < size || q_size < size)
|
| 359 | fortify_panic(__func__);
|
| 360 | return __builtin_memmove(p, q, size);
|
| 361 | }
|
| 362 |
|
| 363 | extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
|
| 364 | __FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
|
| 365 | {
|
| 366 | size_t p_size = __builtin_object_size(p, 0);
|
| 367 | if (__builtin_constant_p(size) && p_size < size)
|
| 368 | __read_overflow();
|
| 369 | if (p_size < size)
|
| 370 | fortify_panic(__func__);
|
| 371 | return __real_memscan(p, c, size);
|
| 372 | }
|
| 373 |
|
| 374 | __FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
|
| 375 | {
|
| 376 | size_t p_size = __builtin_object_size(p, 0);
|
| 377 | size_t q_size = __builtin_object_size(q, 0);
|
| 378 | if (__builtin_constant_p(size)) {
|
| 379 | if (p_size < size)
|
| 380 | __read_overflow();
|
| 381 | if (q_size < size)
|
| 382 | __read_overflow2();
|
| 383 | }
|
| 384 | if (p_size < size || q_size < size)
|
| 385 | fortify_panic(__func__);
|
| 386 | return __builtin_memcmp(p, q, size);
|
| 387 | }
|
| 388 |
|
| 389 | __FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
|
| 390 | {
|
| 391 | size_t p_size = __builtin_object_size(p, 0);
|
| 392 | if (__builtin_constant_p(size) && p_size < size)
|
| 393 | __read_overflow();
|
| 394 | if (p_size < size)
|
| 395 | fortify_panic(__func__);
|
| 396 | return __builtin_memchr(p, c, size);
|
| 397 | }
|
| 398 |
|
| 399 | void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
|
| 400 | __FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
|
| 401 | {
|
| 402 | size_t p_size = __builtin_object_size(p, 0);
|
| 403 | if (__builtin_constant_p(size) && p_size < size)
|
| 404 | __read_overflow();
|
| 405 | if (p_size < size)
|
| 406 | fortify_panic(__func__);
|
| 407 | return __real_memchr_inv(p, c, size);
|
| 408 | }
|
| 409 |
|
| 410 | extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
|
| 411 | __FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
|
| 412 | {
|
| 413 | size_t p_size = __builtin_object_size(p, 0);
|
| 414 | if (__builtin_constant_p(size) && p_size < size)
|
| 415 | __read_overflow();
|
| 416 | if (p_size < size)
|
| 417 | fortify_panic(__func__);
|
| 418 | return __real_kmemdup(p, size, gfp);
|
| 419 | }
|
| 420 |
|
| 421 |
|
| 422 | __FORTIFY_INLINE char *strcpy(char *p, const char *q)
|
| 423 | {
|
| 424 | size_t p_size = __builtin_object_size(p, 0);
|
| 425 | size_t q_size = __builtin_object_size(q, 0);
|
| 426 | if (p_size == (size_t)-1 && q_size == (size_t)-1)
|
| 427 | return __builtin_strcpy(p, q);
|
| 428 | memcpy(p, q, strlen(q) + 1);
|
| 429 | return p;
|
| 430 | }
|
| 431 |
|
| 432 | #endif
|
| 433 |
|
| 434 | |
| 435 | * memcpy_and_pad - Copy one buffer to another with padding
|
| 436 | * @dest: Where to copy to
|
| 437 | * @dest_len: The destination buffer size
|
| 438 | * @src: Where to copy from
|
| 439 | * @count: The number of bytes to copy
|
| 440 | * @pad: Character to use for padding if space is left in destination.
|
| 441 |
|
| 442 | static inline void memcpy_and_pad(void *dest, size_t dest_len,
|
| 443 | const void *src, size_t count, int pad)
|
| 444 | {
|
| 445 | if (dest_len > count) {
|
| 446 | memcpy(dest, src, count);
|
| 447 | memset(dest + count, pad, dest_len - count);
|
| 448 | } else
|
| 449 | memcpy(dest, src, dest_len);
|
| 450 | }
|
| 451 |
|
| 452 | #endif
|