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 <linux/errno.h>
10#include <stdarg.h>
11#include <uapi/linux/string.h>
12
13extern char *strndup_user(const char __user *, long);
14extern void *memdup_user(const void __user *, size_t);
15extern void *vmemdup_user(const void __user *, size_t);
16extern void *memdup_user_nul(const void __user *, size_t);
17
18
19
20
21#include <asm/string.h>
22
23#ifndef __HAVE_ARCH_STRCPY
24extern char * strcpy(char *,const char *);
25#endif
26#ifndef __HAVE_ARCH_STRNCPY
27extern char * strncpy(char *,const char *, __kernel_size_t);
28#endif
29#ifndef __HAVE_ARCH_STRLCPY
30size_t strlcpy(char *, const char *, size_t);
31#endif
32#ifndef __HAVE_ARCH_STRSCPY
33ssize_t strscpy(char *, const char *, size_t);
34#endif
35
36
37ssize_t strscpy_pad(char *dest, const char *src, size_t count);
38
39#ifndef __HAVE_ARCH_STRCAT
40extern char * strcat(char *, const char *);
41#endif
42#ifndef __HAVE_ARCH_STRNCAT
43extern char * strncat(char *, const char *, __kernel_size_t);
44#endif
45#ifndef __HAVE_ARCH_STRLCAT
46extern size_t strlcat(char *, const char *, __kernel_size_t);
47#endif
48#ifndef __HAVE_ARCH_STRCMP
49extern int strcmp(const char *,const char *);
50#endif
51#ifndef __HAVE_ARCH_STRNCMP
52extern int strncmp(const char *,const char *,__kernel_size_t);
53#endif
54#ifndef __HAVE_ARCH_STRCASECMP
55extern int strcasecmp(const char *s1, const char *s2);
56#endif
57#ifndef __HAVE_ARCH_STRNCASECMP
58extern int strncasecmp(const char *s1, const char *s2, size_t n);
59#endif
60#ifndef __HAVE_ARCH_STRCHR
61extern char * strchr(const char *,int);
62#endif
63#ifndef __HAVE_ARCH_STRCHRNUL
64extern char * strchrnul(const char *,int);
65#endif
66extern char * strnchrnul(const char *, size_t, int);
67#ifndef __HAVE_ARCH_STRNCHR
68extern char * strnchr(const char *, size_t, int);
69#endif
70#ifndef __HAVE_ARCH_STRRCHR
71extern char * strrchr(const char *,int);
72#endif
73extern char * __must_check skip_spaces(const char *);
74
75extern char *strim(char *);
76
77static inline __must_check char *strstrip(char *str)
78{
79 return strim(str);
80}
81
82#ifndef __HAVE_ARCH_STRSTR
83extern char * strstr(const char *, const char *);
84#endif
85#ifndef __HAVE_ARCH_STRNSTR
86extern char * strnstr(const char *, const char *, size_t);
87#endif
88#ifndef __HAVE_ARCH_STRLEN
89extern __kernel_size_t strlen(const char *);
90#endif
91#ifndef __HAVE_ARCH_STRNLEN
92extern __kernel_size_t strnlen(const char *,__kernel_size_t);
93#endif
94#ifndef __HAVE_ARCH_STRPBRK
95extern char * strpbrk(const char *,const char *);
96#endif
97#ifndef __HAVE_ARCH_STRSEP
98extern char * strsep(char **,const char *);
99#endif
100#ifndef __HAVE_ARCH_STRSPN
101extern __kernel_size_t strspn(const char *,const char *);
102#endif
103#ifndef __HAVE_ARCH_STRCSPN
104extern __kernel_size_t strcspn(const char *,const char *);
105#endif
106
107#ifndef __HAVE_ARCH_MEMSET
108extern void * memset(void *,int,__kernel_size_t);
109#endif
110
111#ifndef __HAVE_ARCH_MEMSET16
112extern void *memset16(uint16_t *, uint16_t, __kernel_size_t);
113#endif
114
115#ifndef __HAVE_ARCH_MEMSET32
116extern void *memset32(uint32_t *, uint32_t, __kernel_size_t);
117#endif
118
119#ifndef __HAVE_ARCH_MEMSET64
120extern void *memset64(uint64_t *, uint64_t, __kernel_size_t);
121#endif
122
123static inline void *memset_l(unsigned long *p, unsigned long v,
124 __kernel_size_t n)
125{
126 if (BITS_PER_LONG == 32)
127 return memset32((uint32_t *)p, v, n);
128 else
129 return memset64((uint64_t *)p, v, n);
130}
131
132static inline void *memset_p(void **p, void *v, __kernel_size_t n)
133{
134 if (BITS_PER_LONG == 32)
135 return memset32((uint32_t *)p, (uintptr_t)v, n);
136 else
137 return memset64((uint64_t *)p, (uintptr_t)v, n);
138}
139
140extern void **__memcat_p(void **a, void **b);
141#define memcat_p(a, b) ({ \
142 BUILD_BUG_ON_MSG(!__same_type(*(a), *(b)), \
143 "type mismatch in memcat_p()"); \
144 (typeof(*a) *)__memcat_p((void **)(a), (void **)(b)); \
145})
146
147#ifndef __HAVE_ARCH_MEMCPY
148extern void * memcpy(void *,const void *,__kernel_size_t);
149#endif
150#ifndef __HAVE_ARCH_MEMMOVE
151extern void * memmove(void *,const void *,__kernel_size_t);
152#endif
153#ifndef __HAVE_ARCH_MEMSCAN
154extern void * memscan(void *,int,__kernel_size_t);
155#endif
156#ifndef __HAVE_ARCH_MEMCMP
157extern int memcmp(const void *,const void *,__kernel_size_t);
158#endif
159#ifndef __HAVE_ARCH_BCMP
160extern int bcmp(const void *,const void *,__kernel_size_t);
161#endif
162#ifndef __HAVE_ARCH_MEMCHR
163extern void * memchr(const void *,int,__kernel_size_t);
164#endif
165#ifndef __HAVE_ARCH_MEMCPY_FLUSHCACHE
166static inline void memcpy_flushcache(void *dst, const void *src, size_t cnt)
167{
168 memcpy(dst, src, cnt);
169}
170#endif
171
172void *memchr_inv(const void *s, int c, size_t n);
173char *strreplace(char *s, char old, char new);
174
175extern void kfree_const(const void *x);
176
177extern char *kstrdup(const char *s, gfp_t gfp) __malloc;
178extern const char *kstrdup_const(const char *s, gfp_t gfp);
179extern char *kstrndup(const char *s, size_t len, gfp_t gfp);
180extern void *kmemdup(const void *src, size_t len, gfp_t gfp);
181extern char *kmemdup_nul(const char *s, size_t len, gfp_t gfp);
182
183extern char **argv_split(gfp_t gfp, const char *str, int *argcp);
184extern void argv_free(char **argv);
185
186extern bool sysfs_streq(const char *s1, const char *s2);
187extern int kstrtobool(const char *s, bool *res);
188static inline int strtobool(const char *s, bool *res)
189{
190 return kstrtobool(s, res);
191}
192
193int match_string(const char * const *array, size_t n, const char *string);
194int __sysfs_match_string(const char * const *array, size_t n, const char *s);
195
196
197
198
199
200
201
202
203#define sysfs_match_string(_a, _s) __sysfs_match_string(_a, ARRAY_SIZE(_a), _s)
204
205#ifdef CONFIG_BINARY_PRINTF
206int vbin_printf(u32 *bin_buf, size_t size, const char *fmt, va_list args);
207int bstr_printf(char *buf, size_t size, const char *fmt, const u32 *bin_buf);
208int bprintf(u32 *bin_buf, size_t size, const char *fmt, ...) __printf(3, 4);
209#endif
210
211extern ssize_t memory_read_from_buffer(void *to, size_t count, loff_t *ppos,
212 const void *from, size_t available);
213
214int ptr_to_hashval(const void *ptr, unsigned long *hashval_out);
215
216
217
218
219
220
221static inline bool strstarts(const char *str, const char *prefix)
222{
223 return strncmp(str, prefix, strlen(prefix)) == 0;
224}
225
226size_t memweight(const void *ptr, size_t bytes);
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242static inline void memzero_explicit(void *s, size_t count)
243{
244 memset(s, 0, count);
245 barrier_data(s);
246}
247
248
249
250
251
252
253static inline const char *kbasename(const char *path)
254{
255 const char *tail = strrchr(path, '/');
256 return tail ? tail + 1 : path;
257}
258
259#define __FORTIFY_INLINE extern __always_inline __attribute__((gnu_inline))
260#define __RENAME(x) __asm__(#x)
261
262void fortify_panic(const char *name) __noreturn __cold;
263void __read_overflow(void) __compiletime_error("detected read beyond size of object passed as 1st parameter");
264void __read_overflow2(void) __compiletime_error("detected read beyond size of object passed as 2nd parameter");
265void __read_overflow3(void) __compiletime_error("detected read beyond size of object passed as 3rd parameter");
266void __write_overflow(void) __compiletime_error("detected write beyond size of object passed as 1st parameter");
267
268#if !defined(__NO_FORTIFY) && defined(__OPTIMIZE__) && defined(CONFIG_FORTIFY_SOURCE)
269
270#if defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KASAN_SW_TAGS)
271extern void *__underlying_memchr(const void *p, int c, __kernel_size_t size) __RENAME(memchr);
272extern int __underlying_memcmp(const void *p, const void *q, __kernel_size_t size) __RENAME(memcmp);
273extern void *__underlying_memcpy(void *p, const void *q, __kernel_size_t size) __RENAME(memcpy);
274extern void *__underlying_memmove(void *p, const void *q, __kernel_size_t size) __RENAME(memmove);
275extern void *__underlying_memset(void *p, int c, __kernel_size_t size) __RENAME(memset);
276extern char *__underlying_strcat(char *p, const char *q) __RENAME(strcat);
277extern char *__underlying_strcpy(char *p, const char *q) __RENAME(strcpy);
278extern __kernel_size_t __underlying_strlen(const char *p) __RENAME(strlen);
279extern char *__underlying_strncat(char *p, const char *q, __kernel_size_t count) __RENAME(strncat);
280extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size) __RENAME(strncpy);
281#else
282#define __underlying_memchr __builtin_memchr
283#define __underlying_memcmp __builtin_memcmp
284#define __underlying_memcpy __builtin_memcpy
285#define __underlying_memmove __builtin_memmove
286#define __underlying_memset __builtin_memset
287#define __underlying_strcat __builtin_strcat
288#define __underlying_strcpy __builtin_strcpy
289#define __underlying_strlen __builtin_strlen
290#define __underlying_strncat __builtin_strncat
291#define __underlying_strncpy __builtin_strncpy
292#endif
293
294__FORTIFY_INLINE char *strncpy(char *p, const char *q, __kernel_size_t size)
295{
296 size_t p_size = __builtin_object_size(p, 1);
297 if (__builtin_constant_p(size) && p_size < size)
298 __write_overflow();
299 if (p_size < size)
300 fortify_panic(__func__);
301 return __underlying_strncpy(p, q, size);
302}
303
304__FORTIFY_INLINE char *strcat(char *p, const char *q)
305{
306 size_t p_size = __builtin_object_size(p, 1);
307 if (p_size == (size_t)-1)
308 return __underlying_strcat(p, q);
309 if (strlcat(p, q, p_size) >= p_size)
310 fortify_panic(__func__);
311 return p;
312}
313
314__FORTIFY_INLINE __kernel_size_t strlen(const char *p)
315{
316 __kernel_size_t ret;
317 size_t p_size = __builtin_object_size(p, 1);
318
319
320 if (p_size == (size_t)-1 ||
321 (__builtin_constant_p(p[p_size - 1]) && p[p_size - 1] == '\0'))
322 return __underlying_strlen(p);
323 ret = strnlen(p, p_size);
324 if (p_size <= ret)
325 fortify_panic(__func__);
326 return ret;
327}
328
329extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
330__FORTIFY_INLINE __kernel_size_t strnlen(const char *p, __kernel_size_t maxlen)
331{
332 size_t p_size = __builtin_object_size(p, 1);
333 __kernel_size_t ret = __real_strnlen(p, maxlen < p_size ? maxlen : p_size);
334 if (p_size <= ret && maxlen != ret)
335 fortify_panic(__func__);
336 return ret;
337}
338
339
340extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
341__FORTIFY_INLINE size_t strlcpy(char *p, const char *q, size_t size)
342{
343 size_t ret;
344 size_t p_size = __builtin_object_size(p, 1);
345 size_t q_size = __builtin_object_size(q, 1);
346 if (p_size == (size_t)-1 && q_size == (size_t)-1)
347 return __real_strlcpy(p, q, size);
348 ret = strlen(q);
349 if (size) {
350 size_t len = (ret >= size) ? size - 1 : ret;
351 if (__builtin_constant_p(len) && len >= p_size)
352 __write_overflow();
353 if (len >= p_size)
354 fortify_panic(__func__);
355 __underlying_memcpy(p, q, len);
356 p[len] = '\0';
357 }
358 return ret;
359}
360
361
362extern ssize_t __real_strscpy(char *, const char *, size_t) __RENAME(strscpy);
363__FORTIFY_INLINE ssize_t strscpy(char *p, const char *q, size_t size)
364{
365 size_t len;
366
367 size_t p_size = __builtin_object_size(p, 1);
368 size_t q_size = __builtin_object_size(q, 1);
369
370
371 if (p_size == (size_t) -1 && q_size == (size_t) -1)
372 return __real_strscpy(p, q, size);
373
374
375
376
377
378 if (__builtin_constant_p(size) && size > p_size)
379 __write_overflow();
380
381
382
383
384
385 len = strnlen(q, size);
386
387
388
389
390
391 len = len == size ? size : len + 1;
392
393
394
395
396
397 if (len > p_size)
398 fortify_panic(__func__);
399
400
401
402
403
404
405 return __real_strscpy(p, q, len);
406}
407
408
409__FORTIFY_INLINE char *strncat(char *p, const char *q, __kernel_size_t count)
410{
411 size_t p_len, copy_len;
412 size_t p_size = __builtin_object_size(p, 1);
413 size_t q_size = __builtin_object_size(q, 1);
414 if (p_size == (size_t)-1 && q_size == (size_t)-1)
415 return __underlying_strncat(p, q, count);
416 p_len = strlen(p);
417 copy_len = strnlen(q, count);
418 if (p_size < p_len + copy_len + 1)
419 fortify_panic(__func__);
420 __underlying_memcpy(p + p_len, q, copy_len);
421 p[p_len + copy_len] = '\0';
422 return p;
423}
424
425__FORTIFY_INLINE void *memset(void *p, int c, __kernel_size_t size)
426{
427 size_t p_size = __builtin_object_size(p, 0);
428 if (__builtin_constant_p(size) && p_size < size)
429 __write_overflow();
430 if (p_size < size)
431 fortify_panic(__func__);
432 return __underlying_memset(p, c, size);
433}
434
435__FORTIFY_INLINE void *memcpy(void *p, const void *q, __kernel_size_t size)
436{
437 size_t p_size = __builtin_object_size(p, 0);
438 size_t q_size = __builtin_object_size(q, 0);
439 if (__builtin_constant_p(size)) {
440 if (p_size < size)
441 __write_overflow();
442 if (q_size < size)
443 __read_overflow2();
444 }
445 if (p_size < size || q_size < size)
446 fortify_panic(__func__);
447 return __underlying_memcpy(p, q, size);
448}
449
450__FORTIFY_INLINE void *memmove(void *p, const void *q, __kernel_size_t size)
451{
452 size_t p_size = __builtin_object_size(p, 0);
453 size_t q_size = __builtin_object_size(q, 0);
454 if (__builtin_constant_p(size)) {
455 if (p_size < size)
456 __write_overflow();
457 if (q_size < size)
458 __read_overflow2();
459 }
460 if (p_size < size || q_size < size)
461 fortify_panic(__func__);
462 return __underlying_memmove(p, q, size);
463}
464
465extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
466__FORTIFY_INLINE void *memscan(void *p, int c, __kernel_size_t size)
467{
468 size_t p_size = __builtin_object_size(p, 0);
469 if (__builtin_constant_p(size) && p_size < size)
470 __read_overflow();
471 if (p_size < size)
472 fortify_panic(__func__);
473 return __real_memscan(p, c, size);
474}
475
476__FORTIFY_INLINE int memcmp(const void *p, const void *q, __kernel_size_t size)
477{
478 size_t p_size = __builtin_object_size(p, 0);
479 size_t q_size = __builtin_object_size(q, 0);
480 if (__builtin_constant_p(size)) {
481 if (p_size < size)
482 __read_overflow();
483 if (q_size < size)
484 __read_overflow2();
485 }
486 if (p_size < size || q_size < size)
487 fortify_panic(__func__);
488 return __underlying_memcmp(p, q, size);
489}
490
491__FORTIFY_INLINE void *memchr(const void *p, int c, __kernel_size_t size)
492{
493 size_t p_size = __builtin_object_size(p, 0);
494 if (__builtin_constant_p(size) && p_size < size)
495 __read_overflow();
496 if (p_size < size)
497 fortify_panic(__func__);
498 return __underlying_memchr(p, c, size);
499}
500
501void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
502__FORTIFY_INLINE void *memchr_inv(const void *p, int c, size_t size)
503{
504 size_t p_size = __builtin_object_size(p, 0);
505 if (__builtin_constant_p(size) && p_size < size)
506 __read_overflow();
507 if (p_size < size)
508 fortify_panic(__func__);
509 return __real_memchr_inv(p, c, size);
510}
511
512extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
513__FORTIFY_INLINE void *kmemdup(const void *p, size_t size, gfp_t gfp)
514{
515 size_t p_size = __builtin_object_size(p, 0);
516 if (__builtin_constant_p(size) && p_size < size)
517 __read_overflow();
518 if (p_size < size)
519 fortify_panic(__func__);
520 return __real_kmemdup(p, size, gfp);
521}
522
523
524__FORTIFY_INLINE char *strcpy(char *p, const char *q)
525{
526 size_t p_size = __builtin_object_size(p, 1);
527 size_t q_size = __builtin_object_size(q, 1);
528 size_t size;
529 if (p_size == (size_t)-1 && q_size == (size_t)-1)
530 return __underlying_strcpy(p, q);
531 size = strlen(q) + 1;
532
533 if (p_size < size)
534 fortify_panic(__func__);
535 memcpy(p, q, size);
536 return p;
537}
538
539
540#undef __underlying_memchr
541#undef __underlying_memcmp
542#undef __underlying_memcpy
543#undef __underlying_memmove
544#undef __underlying_memset
545#undef __underlying_strcat
546#undef __underlying_strcpy
547#undef __underlying_strlen
548#undef __underlying_strncat
549#undef __underlying_strncpy
550#endif
551
552
553
554
555
556
557
558
559
560static inline void memcpy_and_pad(void *dest, size_t dest_len,
561 const void *src, size_t count, int pad)
562{
563 if (dest_len > count) {
564 memcpy(dest, src, count);
565 memset(dest + count, pad, dest_len - count);
566 } else
567 memcpy(dest, src, dest_len);
568}
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585static __always_inline size_t str_has_prefix(const char *str, const char *prefix)
586{
587 size_t len = strlen(prefix);
588 return strncmp(str, prefix, len) == 0 ? len : 0;
589}
590
591#endif
592