22#ifndef _LINUX_FORTIFY_STRING_H_
33#define _LINUX_FORTIFY_STRING_H_
44
5+ #include <linux/bitfield.h>
56#include <linux/bug.h>
67#include <linux/const.h>
78#include <linux/limits.h>
89
910#define __FORTIFY_INLINE extern __always_inline __gnu_inline __overloadable
1011#define __RENAME (x ) __asm__(#x)
1112
12- void fortify_panic (const char * name ) __noreturn __cold ;
13+ #define FORTIFY_REASON_DIR (r ) FIELD_GET(BIT(0), r)
14+ #define FORTIFY_REASON_FUNC (r ) FIELD_GET(GENMASK(7, 1), r)
15+ #define FORTIFY_REASON (func , write ) (FIELD_PREP(BIT(0), write) | \
16+ FIELD_PREP(GENMASK(7, 1), func))
17+
18+ #define fortify_panic (func , write ) \
19+ __fortify_panic(FORTIFY_REASON(func, write))
20+
21+ #define FORTIFY_READ 0
22+ #define FORTIFY_WRITE 1
23+
24+ #define EACH_FORTIFY_FUNC (macro ) \
25+ macro(strncpy), \
26+ macro(strnlen), \
27+ macro(strlen), \
28+ macro(strscpy), \
29+ macro(strlcat), \
30+ macro(strcat), \
31+ macro(strncat), \
32+ macro(memset), \
33+ macro(memcpy), \
34+ macro(memmove), \
35+ macro(memscan), \
36+ macro(memcmp), \
37+ macro(memchr), \
38+ macro(memchr_inv), \
39+ macro(kmemdup), \
40+ macro(strcpy), \
41+ macro(UNKNOWN),
42+
43+ #define MAKE_FORTIFY_FUNC (func ) FORTIFY_FUNC_##func
44+
45+ enum fortify_func {
46+ EACH_FORTIFY_FUNC (MAKE_FORTIFY_FUNC )
47+ };
48+
49+ void __fortify_report (const u8 reason );
50+ void __fortify_panic (const u8 reason ) __cold __noreturn ;
1351void __read_overflow (void ) __compiletime_error ("detected read beyond size of object (1st parameter)" );
1452void __read_overflow2 (void ) __compiletime_error ("detected read beyond size of object (2nd parameter)" );
1553void __read_overflow2_field (size_t avail , size_t wanted ) __compiletime_warning ("detected read beyond size of field (2nd parameter); maybe use struct_group()?" );
@@ -143,7 +181,7 @@ char *strncpy(char * const POS p, const char *q, __kernel_size_t size)
143181 if (__compiletime_lessthan (p_size , size ))
144182 __write_overflow ();
145183 if (p_size < size )
146- fortify_panic (__func__ );
184+ fortify_panic (FORTIFY_FUNC_strncpy , FORTIFY_WRITE );
147185 return __underlying_strncpy (p , q , size );
148186}
149187
@@ -174,7 +212,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
174212 /* Do not check characters beyond the end of p. */
175213 ret = __real_strnlen (p , maxlen < p_size ? maxlen : p_size );
176214 if (p_size <= ret && maxlen != ret )
177- fortify_panic (__func__ );
215+ fortify_panic (FORTIFY_FUNC_strnlen , FORTIFY_READ );
178216 return ret ;
179217}
180218
@@ -210,7 +248,7 @@ __kernel_size_t __fortify_strlen(const char * const POS p)
210248 return __underlying_strlen (p );
211249 ret = strnlen (p , p_size );
212250 if (p_size <= ret )
213- fortify_panic (__func__ );
251+ fortify_panic (FORTIFY_FUNC_strlen , FORTIFY_READ );
214252 return ret ;
215253}
216254
@@ -261,7 +299,7 @@ __FORTIFY_INLINE ssize_t sized_strscpy(char * const POS p, const char * const PO
261299 * p_size.
262300 */
263301 if (len > p_size )
264- fortify_panic (__func__ );
302+ fortify_panic (FORTIFY_FUNC_strscpy , FORTIFY_WRITE );
265303
266304 /*
267305 * We can now safely call vanilla strscpy because we are protected from:
@@ -319,7 +357,7 @@ size_t strlcat(char * const POS p, const char * const POS q, size_t avail)
319357
320358 /* Give up if string is already overflowed. */
321359 if (p_size <= p_len )
322- fortify_panic (__func__ );
360+ fortify_panic (FORTIFY_FUNC_strlcat , FORTIFY_READ );
323361
324362 if (actual >= avail ) {
325363 copy_len = avail - p_len - 1 ;
@@ -328,7 +366,7 @@ size_t strlcat(char * const POS p, const char * const POS q, size_t avail)
328366
329367 /* Give up if copy will overflow. */
330368 if (p_size <= actual )
331- fortify_panic (__func__ );
369+ fortify_panic (FORTIFY_FUNC_strlcat , FORTIFY_WRITE );
332370 __underlying_memcpy (p + p_len , q , copy_len );
333371 p [actual ] = '\0' ;
334372
@@ -357,7 +395,7 @@ char *strcat(char * const POS p, const char *q)
357395 const size_t p_size = __member_size (p );
358396
359397 if (strlcat (p , q , p_size ) >= p_size )
360- fortify_panic (__func__ );
398+ fortify_panic (FORTIFY_FUNC_strcat , FORTIFY_WRITE );
361399 return p ;
362400}
363401
@@ -393,7 +431,7 @@ char *strncat(char * const POS p, const char * const POS q, __kernel_size_t coun
393431 p_len = strlen (p );
394432 copy_len = strnlen (q , count );
395433 if (p_size < p_len + copy_len + 1 )
396- fortify_panic (__func__ );
434+ fortify_panic (FORTIFY_FUNC_strncat , FORTIFY_WRITE );
397435 __underlying_memcpy (p + p_len , q , copy_len );
398436 p [p_len + copy_len ] = '\0' ;
399437 return p ;
@@ -434,7 +472,7 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size,
434472 * lengths are unknown.)
435473 */
436474 if (p_size != SIZE_MAX && p_size < size )
437- fortify_panic ("memset" );
475+ fortify_panic (FORTIFY_FUNC_memset , FORTIFY_WRITE );
438476}
439477
440478#define __fortify_memset_chk (p , c , size , p_size , p_size_field ) ({ \
@@ -488,7 +526,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
488526 const size_t q_size ,
489527 const size_t p_size_field ,
490528 const size_t q_size_field ,
491- const char * func )
529+ const u8 func )
492530{
493531 if (__builtin_constant_p (size )) {
494532 /*
@@ -532,9 +570,10 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
532570 * (The SIZE_MAX test is to optimize away checks where the buffer
533571 * lengths are unknown.)
534572 */
535- if ((p_size != SIZE_MAX && p_size < size ) ||
536- (q_size != SIZE_MAX && q_size < size ))
537- fortify_panic (func );
573+ if (p_size != SIZE_MAX && p_size < size )
574+ fortify_panic (func , FORTIFY_WRITE );
575+ else if (q_size != SIZE_MAX && q_size < size )
576+ fortify_panic (func , FORTIFY_READ );
538577
539578 /*
540579 * Warn when writing beyond destination field size.
@@ -567,7 +606,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
567606 const size_t __q_size_field = (q_size_field); \
568607 WARN_ONCE(fortify_memcpy_chk(__fortify_size, __p_size, \
569608 __q_size, __p_size_field, \
570- __q_size_field, # op), \
609+ __q_size_field, FORTIFY_FUNC_ ## op), \
571610 #op ": detected field-spanning write (size %zu) of single %s (size %zu)\n", \
572611 __fortify_size, \
573612 "field \"" #p "\" at " FILE_LINE, \
@@ -634,7 +673,7 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size)
634673 if (__compiletime_lessthan (p_size , size ))
635674 __read_overflow ();
636675 if (p_size < size )
637- fortify_panic (__func__ );
676+ fortify_panic (FORTIFY_FUNC_memscan , FORTIFY_READ );
638677 return __real_memscan (p , c , size );
639678}
640679
@@ -651,7 +690,7 @@ int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t
651690 __read_overflow2 ();
652691 }
653692 if (p_size < size || q_size < size )
654- fortify_panic (__func__ );
693+ fortify_panic (FORTIFY_FUNC_memcmp , FORTIFY_READ );
655694 return __underlying_memcmp (p , q , size );
656695}
657696
@@ -663,7 +702,7 @@ void *memchr(const void * const POS0 p, int c, __kernel_size_t size)
663702 if (__compiletime_lessthan (p_size , size ))
664703 __read_overflow ();
665704 if (p_size < size )
666- fortify_panic (__func__ );
705+ fortify_panic (FORTIFY_FUNC_memchr , FORTIFY_READ );
667706 return __underlying_memchr (p , c , size );
668707}
669708
@@ -675,7 +714,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size)
675714 if (__compiletime_lessthan (p_size , size ))
676715 __read_overflow ();
677716 if (p_size < size )
678- fortify_panic (__func__ );
717+ fortify_panic (FORTIFY_FUNC_memchr_inv , FORTIFY_READ );
679718 return __real_memchr_inv (p , c , size );
680719}
681720
@@ -688,7 +727,7 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp
688727 if (__compiletime_lessthan (p_size , size ))
689728 __read_overflow ();
690729 if (p_size < size )
691- fortify_panic (__func__ );
730+ fortify_panic (FORTIFY_FUNC_kmemdup , FORTIFY_READ );
692731 return __real_kmemdup (p , size , gfp );
693732}
694733
@@ -725,7 +764,7 @@ char *strcpy(char * const POS p, const char * const POS q)
725764 __write_overflow ();
726765 /* Run-time check for dynamic size overflow. */
727766 if (p_size < size )
728- fortify_panic (__func__ );
767+ fortify_panic (FORTIFY_FUNC_strcpy , FORTIFY_WRITE );
729768 __underlying_memcpy (p , q , size );
730769 return p ;
731770}
0 commit comments