1616 FIELD_PREP(GENMASK(7, 1), func))
1717
1818#ifndef fortify_panic
19- # define fortify_panic (func , write , retfail ) \
20- __fortify_panic(FORTIFY_REASON(func, write))
19+ # define fortify_panic (func , write , avail , size , retfail ) \
20+ __fortify_panic(FORTIFY_REASON(func, write), avail, size )
2121#endif
2222
2323#define FORTIFY_READ 0
@@ -48,8 +48,8 @@ enum fortify_func {
4848 EACH_FORTIFY_FUNC (MAKE_FORTIFY_FUNC )
4949};
5050
51- void __fortify_report (const u8 reason );
52- void __fortify_panic (const u8 reason ) __cold __noreturn ;
51+ void __fortify_report (const u8 reason , const size_t avail , const size_t size );
52+ void __fortify_panic (const u8 reason , const size_t avail , const size_t size ) __cold __noreturn ;
5353void __read_overflow (void ) __compiletime_error ("detected read beyond size of object (1st parameter)" );
5454void __read_overflow2 (void ) __compiletime_error ("detected read beyond size of object (2nd parameter)" );
5555void __read_overflow2_field (size_t avail , size_t wanted ) __compiletime_warning ("detected read beyond size of field (2nd parameter); maybe use struct_group()?" );
@@ -183,7 +183,7 @@ char *strncpy(char * const POS p, const char *q, __kernel_size_t size)
183183 if (__compiletime_lessthan (p_size , size ))
184184 __write_overflow ();
185185 if (p_size < size )
186- fortify_panic (FORTIFY_FUNC_strncpy , FORTIFY_WRITE , p );
186+ fortify_panic (FORTIFY_FUNC_strncpy , FORTIFY_WRITE , p_size , size , p );
187187 return __underlying_strncpy (p , q , size );
188188}
189189
@@ -214,7 +214,7 @@ __FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size
214214 /* Do not check characters beyond the end of p. */
215215 ret = __real_strnlen (p , maxlen < p_size ? maxlen : p_size );
216216 if (p_size <= ret && maxlen != ret )
217- fortify_panic (FORTIFY_FUNC_strnlen , FORTIFY_READ , ret );
217+ fortify_panic (FORTIFY_FUNC_strnlen , FORTIFY_READ , p_size , ret + 1 , ret );
218218 return ret ;
219219}
220220
@@ -250,7 +250,7 @@ __kernel_size_t __fortify_strlen(const char * const POS p)
250250 return __underlying_strlen (p );
251251 ret = strnlen (p , p_size );
252252 if (p_size <= ret )
253- fortify_panic (FORTIFY_FUNC_strlen , FORTIFY_READ , ret );
253+ fortify_panic (FORTIFY_FUNC_strlen , FORTIFY_READ , p_size , ret + 1 , ret );
254254 return ret ;
255255}
256256
@@ -300,8 +300,8 @@ __FORTIFY_INLINE ssize_t sized_strscpy(char * const POS p, const char * const PO
300300 * Generate a runtime write overflow error if len is greater than
301301 * p_size.
302302 */
303- if (len > p_size )
304- fortify_panic (FORTIFY_FUNC_strscpy , FORTIFY_WRITE , - E2BIG );
303+ if (p_size < len )
304+ fortify_panic (FORTIFY_FUNC_strscpy , FORTIFY_WRITE , p_size , len , - E2BIG );
305305
306306 /*
307307 * We can now safely call vanilla strscpy because we are protected from:
@@ -359,7 +359,7 @@ size_t strlcat(char * const POS p, const char * const POS q, size_t avail)
359359
360360 /* Give up if string is already overflowed. */
361361 if (p_size <= p_len )
362- fortify_panic (FORTIFY_FUNC_strlcat , FORTIFY_READ , wanted );
362+ fortify_panic (FORTIFY_FUNC_strlcat , FORTIFY_READ , p_size , p_len + 1 , wanted );
363363
364364 if (actual >= avail ) {
365365 copy_len = avail - p_len - 1 ;
@@ -368,7 +368,7 @@ size_t strlcat(char * const POS p, const char * const POS q, size_t avail)
368368
369369 /* Give up if copy will overflow. */
370370 if (p_size <= actual )
371- fortify_panic (FORTIFY_FUNC_strlcat , FORTIFY_WRITE , wanted );
371+ fortify_panic (FORTIFY_FUNC_strlcat , FORTIFY_WRITE , p_size , actual + 1 , wanted );
372372 __underlying_memcpy (p + p_len , q , copy_len );
373373 p [actual ] = '\0' ;
374374
@@ -395,9 +395,10 @@ __FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2)
395395char * strcat (char * const POS p , const char * q )
396396{
397397 const size_t p_size = __member_size (p );
398+ const size_t wanted = strlcat (p , q , p_size );
398399
399- if (strlcat ( p , q , p_size ) >= p_size )
400- fortify_panic (FORTIFY_FUNC_strcat , FORTIFY_WRITE , p );
400+ if (p_size <= wanted )
401+ fortify_panic (FORTIFY_FUNC_strcat , FORTIFY_WRITE , p_size , wanted + 1 , p );
401402 return p ;
402403}
403404
@@ -426,14 +427,15 @@ char *strncat(char * const POS p, const char * const POS q, __kernel_size_t coun
426427{
427428 const size_t p_size = __member_size (p );
428429 const size_t q_size = __member_size (q );
429- size_t p_len , copy_len ;
430+ size_t p_len , copy_len , total ;
430431
431432 if (p_size == SIZE_MAX && q_size == SIZE_MAX )
432433 return __underlying_strncat (p , q , count );
433434 p_len = strlen (p );
434435 copy_len = strnlen (q , count );
435- if (p_size < p_len + copy_len + 1 )
436- fortify_panic (FORTIFY_FUNC_strncat , FORTIFY_WRITE , p );
436+ total = p_len + copy_len + 1 ;
437+ if (p_size < total )
438+ fortify_panic (FORTIFY_FUNC_strncat , FORTIFY_WRITE , p_size , total , p );
437439 __underlying_memcpy (p + p_len , q , copy_len );
438440 p [p_len + copy_len ] = '\0' ;
439441 return p ;
@@ -474,7 +476,7 @@ __FORTIFY_INLINE bool fortify_memset_chk(__kernel_size_t size,
474476 * lengths are unknown.)
475477 */
476478 if (p_size != SIZE_MAX && p_size < size )
477- fortify_panic (FORTIFY_FUNC_memset , FORTIFY_WRITE , true);
479+ fortify_panic (FORTIFY_FUNC_memset , FORTIFY_WRITE , p_size , size , true);
478480 return false;
479481}
480482
@@ -574,9 +576,9 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
574576 * lengths are unknown.)
575577 */
576578 if (p_size != SIZE_MAX && p_size < size )
577- fortify_panic (func , FORTIFY_WRITE , true);
579+ fortify_panic (func , FORTIFY_WRITE , p_size , size , true);
578580 else if (q_size != SIZE_MAX && q_size < size )
579- fortify_panic (func , FORTIFY_READ , true);
581+ fortify_panic (func , FORTIFY_READ , p_size , size , true);
580582
581583 /*
582584 * Warn when writing beyond destination field size.
@@ -676,7 +678,7 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size)
676678 if (__compiletime_lessthan (p_size , size ))
677679 __read_overflow ();
678680 if (p_size < size )
679- fortify_panic (FORTIFY_FUNC_memscan , FORTIFY_READ , NULL );
681+ fortify_panic (FORTIFY_FUNC_memscan , FORTIFY_READ , p_size , size , NULL );
680682 return __real_memscan (p , c , size );
681683}
682684
@@ -692,8 +694,10 @@ int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t
692694 if (__compiletime_lessthan (q_size , size ))
693695 __read_overflow2 ();
694696 }
695- if (p_size < size || q_size < size )
696- fortify_panic (FORTIFY_FUNC_memcmp , FORTIFY_READ , INT_MIN );
697+ if (p_size < size )
698+ fortify_panic (FORTIFY_FUNC_memcmp , FORTIFY_READ , p_size , size , INT_MIN );
699+ else if (q_size < size )
700+ fortify_panic (FORTIFY_FUNC_memcmp , FORTIFY_READ , q_size , size , INT_MIN );
697701 return __underlying_memcmp (p , q , size );
698702}
699703
@@ -705,7 +709,7 @@ void *memchr(const void * const POS0 p, int c, __kernel_size_t size)
705709 if (__compiletime_lessthan (p_size , size ))
706710 __read_overflow ();
707711 if (p_size < size )
708- fortify_panic (FORTIFY_FUNC_memchr , FORTIFY_READ , NULL );
712+ fortify_panic (FORTIFY_FUNC_memchr , FORTIFY_READ , p_size , size , NULL );
709713 return __underlying_memchr (p , c , size );
710714}
711715
@@ -717,7 +721,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size)
717721 if (__compiletime_lessthan (p_size , size ))
718722 __read_overflow ();
719723 if (p_size < size )
720- fortify_panic (FORTIFY_FUNC_memchr_inv , FORTIFY_READ , NULL );
724+ fortify_panic (FORTIFY_FUNC_memchr_inv , FORTIFY_READ , p_size , size , NULL );
721725 return __real_memchr_inv (p , c , size );
722726}
723727
@@ -730,7 +734,7 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp
730734 if (__compiletime_lessthan (p_size , size ))
731735 __read_overflow ();
732736 if (p_size < size )
733- fortify_panic (FORTIFY_FUNC_kmemdup , FORTIFY_READ , NULL );
737+ fortify_panic (FORTIFY_FUNC_kmemdup , FORTIFY_READ , p_size , size , NULL );
734738 return __real_kmemdup (p , size , gfp );
735739}
736740
@@ -767,7 +771,7 @@ char *strcpy(char * const POS p, const char * const POS q)
767771 __write_overflow ();
768772 /* Run-time check for dynamic size overflow. */
769773 if (p_size < size )
770- fortify_panic (FORTIFY_FUNC_strcpy , FORTIFY_WRITE , p );
774+ fortify_panic (FORTIFY_FUNC_strcpy , FORTIFY_WRITE , p_size , size , p );
771775 __underlying_memcpy (p , q , size );
772776 return p ;
773777}
0 commit comments