@@ -80,6 +80,11 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size)
80
80
#define POS __pass_object_size(1)
81
81
#define POS0 __pass_object_size(0)
82
82
83
+ #define __compiletime_lessthan (bounds , length ) ( \
84
+ __builtin_constant_p((bounds) < (length)) && \
85
+ (bounds) < (length) \
86
+ )
87
+
83
88
/**
84
89
* strncpy - Copy a string to memory with non-guaranteed NUL padding
85
90
*
@@ -117,7 +122,7 @@ char *strncpy(char * const POS p, const char *q, __kernel_size_t size)
117
122
{
118
123
size_t p_size = __builtin_object_size (p , 1 );
119
124
120
- if (__builtin_constant_p ( size ) && p_size < size )
125
+ if (__compiletime_lessthan ( p_size , size ) )
121
126
__write_overflow ();
122
127
if (p_size < size )
123
128
fortify_panic (__func__ );
@@ -224,7 +229,7 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s
224
229
* If size can be known at compile time and is greater than
225
230
* p_size, generate a compile time write overflow error.
226
231
*/
227
- if (__builtin_constant_p ( size ) && size > p_size )
232
+ if (__compiletime_lessthan ( p_size , size ) )
228
233
__write_overflow ();
229
234
230
235
/*
@@ -281,15 +286,16 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size,
281
286
/*
282
287
* Length argument is a constant expression, so we
283
288
* can perform compile-time bounds checking where
284
- * buffer sizes are known.
289
+ * buffer sizes are also known at compile time .
285
290
*/
286
291
287
292
/* Error when size is larger than enclosing struct. */
288
- if (p_size > p_size_field && p_size < size )
293
+ if (__compiletime_lessthan (p_size_field , p_size ) &&
294
+ __compiletime_lessthan (p_size , size ))
289
295
__write_overflow ();
290
296
291
297
/* Warn when write size is larger than dest field. */
292
- if (p_size_field < size )
298
+ if (__compiletime_lessthan ( p_size_field , size ) )
293
299
__write_overflow_field (p_size_field , size );
294
300
}
295
301
/*
@@ -365,25 +371,28 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
365
371
/*
366
372
* Length argument is a constant expression, so we
367
373
* can perform compile-time bounds checking where
368
- * buffer sizes are known.
374
+ * buffer sizes are also known at compile time .
369
375
*/
370
376
371
377
/* Error when size is larger than enclosing struct. */
372
- if (p_size > p_size_field && p_size < size )
378
+ if (__compiletime_lessthan (p_size_field , p_size ) &&
379
+ __compiletime_lessthan (p_size , size ))
373
380
__write_overflow ();
374
- if (q_size > q_size_field && q_size < size )
381
+ if (__compiletime_lessthan (q_size_field , q_size ) &&
382
+ __compiletime_lessthan (q_size , size ))
375
383
__read_overflow2 ();
376
384
377
385
/* Warn when write size argument larger than dest field. */
378
- if (p_size_field < size )
386
+ if (__compiletime_lessthan ( p_size_field , size ) )
379
387
__write_overflow_field (p_size_field , size );
380
388
/*
381
389
* Warn for source field over-read when building with W=1
382
390
* or when an over-write happened, so both can be fixed at
383
391
* the same time.
384
392
*/
385
- if ((IS_ENABLED (KBUILD_EXTRA_WARN1 ) || p_size_field < size ) &&
386
- q_size_field < size )
393
+ if ((IS_ENABLED (KBUILD_EXTRA_WARN1 ) ||
394
+ __compiletime_lessthan (p_size_field , size )) &&
395
+ __compiletime_lessthan (q_size_field , size ))
387
396
__read_overflow2_field (q_size_field , size );
388
397
}
389
398
/*
@@ -494,7 +503,7 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size)
494
503
{
495
504
size_t p_size = __builtin_object_size (p , 0 );
496
505
497
- if (__builtin_constant_p ( size ) && p_size < size )
506
+ if (__compiletime_lessthan ( p_size , size ) )
498
507
__read_overflow ();
499
508
if (p_size < size )
500
509
fortify_panic (__func__ );
@@ -508,9 +517,9 @@ int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t
508
517
size_t q_size = __builtin_object_size (q , 0 );
509
518
510
519
if (__builtin_constant_p (size )) {
511
- if (p_size < size )
520
+ if (__compiletime_lessthan ( p_size , size ) )
512
521
__read_overflow ();
513
- if (q_size < size )
522
+ if (__compiletime_lessthan ( q_size , size ) )
514
523
__read_overflow2 ();
515
524
}
516
525
if (p_size < size || q_size < size )
@@ -523,7 +532,7 @@ void *memchr(const void * const POS0 p, int c, __kernel_size_t size)
523
532
{
524
533
size_t p_size = __builtin_object_size (p , 0 );
525
534
526
- if (__builtin_constant_p ( size ) && p_size < size )
535
+ if (__compiletime_lessthan ( p_size , size ) )
527
536
__read_overflow ();
528
537
if (p_size < size )
529
538
fortify_panic (__func__ );
@@ -535,7 +544,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size)
535
544
{
536
545
size_t p_size = __builtin_object_size (p , 0 );
537
546
538
- if (__builtin_constant_p ( size ) && p_size < size )
547
+ if (__compiletime_lessthan ( p_size , size ) )
539
548
__read_overflow ();
540
549
if (p_size < size )
541
550
fortify_panic (__func__ );
@@ -547,7 +556,7 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp
547
556
{
548
557
size_t p_size = __builtin_object_size (p , 0 );
549
558
550
- if (__builtin_constant_p ( size ) && p_size < size )
559
+ if (__compiletime_lessthan ( p_size , size ) )
551
560
__read_overflow ();
552
561
if (p_size < size )
553
562
fortify_panic (__func__ );
@@ -563,11 +572,13 @@ char *strcpy(char * const POS p, const char * const POS q)
563
572
size_t size ;
564
573
565
574
/* If neither buffer size is known, immediately give up. */
566
- if (p_size == SIZE_MAX && q_size == SIZE_MAX )
575
+ if (__builtin_constant_p (p_size ) &&
576
+ __builtin_constant_p (q_size ) &&
577
+ p_size == SIZE_MAX && q_size == SIZE_MAX )
567
578
return __underlying_strcpy (p , q );
568
579
size = strlen (q ) + 1 ;
569
580
/* Compile-time check for const size overflow. */
570
- if (__builtin_constant_p ( size ) && p_size < size )
581
+ if (__compiletime_lessthan ( p_size , size ) )
571
582
__write_overflow ();
572
583
/* Run-time check for dynamic size overflow. */
573
584
if (p_size < size )
0 commit comments