Skip to content

Commit 9f7d69c

Browse files
committed
fortify: Convert to struct vs member helpers
In preparation for adding support for __builtin_dynamic_object_size(), wrap each instance of __builtin_object_size(p, N) with either the new __struct_size(p) as __bos(p, 0), or __member_size(p) as __bos(p, 1). This will allow us to replace the definitions with __bdos() next. There are no binary differences from this change. Cc: Nathan Chancellor <[email protected]> Cc: Nick Desaulniers <[email protected]> Cc: Tom Rix <[email protected]> Cc: [email protected] Cc: [email protected] Link: https://lore.kernel.org/lkml/[email protected] Signed-off-by: Kees Cook <[email protected]>
1 parent fa35198 commit 9f7d69c

File tree

1 file changed

+35
-33
lines changed

1 file changed

+35
-33
lines changed

include/linux/fortify-string.h

Lines changed: 35 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ void __write_overflow_field(size_t avail, size_t wanted) __compiletime_warning("
2020
({ \
2121
unsigned char *__p = (unsigned char *)(p); \
2222
size_t __ret = SIZE_MAX; \
23-
size_t __p_size = __builtin_object_size(p, 1); \
23+
size_t __p_size = __member_size(p); \
2424
if (__p_size != SIZE_MAX && \
2525
__builtin_constant_p(*__p)) { \
2626
size_t __p_len = __p_size - 1; \
@@ -72,13 +72,15 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size)
7272
__underlying_memcpy(dst, src, bytes)
7373

7474
/*
75-
* Clang's use of __builtin_object_size() within inlines needs hinting via
76-
* __pass_object_size(). The preference is to only ever use type 1 (member
75+
* Clang's use of __builtin_*object_size() within inlines needs hinting via
76+
* __pass_*object_size(). The preference is to only ever use type 1 (member
7777
* size, rather than struct size), but there remain some stragglers using
7878
* type 0 that will be converted in the future.
7979
*/
80-
#define POS __pass_object_size(1)
81-
#define POS0 __pass_object_size(0)
80+
#define POS __pass_object_size(1)
81+
#define POS0 __pass_object_size(0)
82+
#define __struct_size(p) __builtin_object_size(p, 0)
83+
#define __member_size(p) __builtin_object_size(p, 1)
8284

8385
#define __compiletime_lessthan(bounds, length) ( \
8486
__builtin_constant_p((bounds) < (length)) && \
@@ -120,7 +122,7 @@ extern char *__underlying_strncpy(char *p, const char *q, __kernel_size_t size)
120122
__FORTIFY_INLINE __diagnose_as(__builtin_strncpy, 1, 2, 3)
121123
char *strncpy(char * const POS p, const char *q, __kernel_size_t size)
122124
{
123-
size_t p_size = __builtin_object_size(p, 1);
125+
size_t p_size = __member_size(p);
124126

125127
if (__compiletime_lessthan(p_size, size))
126128
__write_overflow();
@@ -132,7 +134,7 @@ char *strncpy(char * const POS p, const char *q, __kernel_size_t size)
132134
__FORTIFY_INLINE __diagnose_as(__builtin_strcat, 1, 2)
133135
char *strcat(char * const POS p, const char *q)
134136
{
135-
size_t p_size = __builtin_object_size(p, 1);
137+
size_t p_size = __member_size(p);
136138

137139
if (p_size == SIZE_MAX)
138140
return __underlying_strcat(p, q);
@@ -144,7 +146,7 @@ char *strcat(char * const POS p, const char *q)
144146
extern __kernel_size_t __real_strnlen(const char *, __kernel_size_t) __RENAME(strnlen);
145147
__FORTIFY_INLINE __kernel_size_t strnlen(const char * const POS p, __kernel_size_t maxlen)
146148
{
147-
size_t p_size = __builtin_object_size(p, 1);
149+
size_t p_size = __member_size(p);
148150
size_t p_len = __compiletime_strlen(p);
149151
size_t ret;
150152

@@ -174,7 +176,7 @@ __FORTIFY_INLINE __diagnose_as(__builtin_strlen, 1)
174176
__kernel_size_t __fortify_strlen(const char * const POS p)
175177
{
176178
__kernel_size_t ret;
177-
size_t p_size = __builtin_object_size(p, 1);
179+
size_t p_size = __member_size(p);
178180

179181
/* Give up if we don't know how large p is. */
180182
if (p_size == SIZE_MAX)
@@ -189,8 +191,8 @@ __kernel_size_t __fortify_strlen(const char * const POS p)
189191
extern size_t __real_strlcpy(char *, const char *, size_t) __RENAME(strlcpy);
190192
__FORTIFY_INLINE size_t strlcpy(char * const POS p, const char * const POS q, size_t size)
191193
{
192-
size_t p_size = __builtin_object_size(p, 1);
193-
size_t q_size = __builtin_object_size(q, 1);
194+
size_t p_size = __member_size(p);
195+
size_t q_size = __member_size(q);
194196
size_t q_len; /* Full count of source string length. */
195197
size_t len; /* Count of characters going into destination. */
196198

@@ -218,8 +220,8 @@ __FORTIFY_INLINE ssize_t strscpy(char * const POS p, const char * const POS q, s
218220
{
219221
size_t len;
220222
/* Use string size rather than possible enclosing struct size. */
221-
size_t p_size = __builtin_object_size(p, 1);
222-
size_t q_size = __builtin_object_size(q, 1);
223+
size_t p_size = __member_size(p);
224+
size_t q_size = __member_size(q);
223225

224226
/* If we cannot get size of p and q default to call strscpy. */
225227
if (p_size == SIZE_MAX && q_size == SIZE_MAX)
@@ -264,8 +266,8 @@ __FORTIFY_INLINE __diagnose_as(__builtin_strncat, 1, 2, 3)
264266
char *strncat(char * const POS p, const char * const POS q, __kernel_size_t count)
265267
{
266268
size_t p_len, copy_len;
267-
size_t p_size = __builtin_object_size(p, 1);
268-
size_t q_size = __builtin_object_size(q, 1);
269+
size_t p_size = __member_size(p);
270+
size_t q_size = __member_size(q);
269271

270272
if (p_size == SIZE_MAX && q_size == SIZE_MAX)
271273
return __underlying_strncat(p, q, count);
@@ -323,11 +325,11 @@ __FORTIFY_INLINE void fortify_memset_chk(__kernel_size_t size,
323325
})
324326

325327
/*
326-
* __builtin_object_size() must be captured here to avoid evaluating argument
327-
* side-effects further into the macro layers.
328+
* __struct_size() vs __member_size() must be captured here to avoid
329+
* evaluating argument side-effects further into the macro layers.
328330
*/
329331
#define memset(p, c, s) __fortify_memset_chk(p, c, s, \
330-
__builtin_object_size(p, 0), __builtin_object_size(p, 1))
332+
__struct_size(p), __member_size(p))
331333

332334
/*
333335
* To make sure the compiler can enforce protection against buffer overflows,
@@ -420,7 +422,7 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
420422
* fake flexible arrays, until they are all converted to
421423
* proper flexible arrays.
422424
*
423-
* The implementation of __builtin_object_size() behaves
425+
* The implementation of __builtin_*object_size() behaves
424426
* like sizeof() when not directly referencing a flexible
425427
* array member, which means there will be many bounds checks
426428
* that will appear at run-time, without a way for them to be
@@ -486,22 +488,22 @@ __FORTIFY_INLINE bool fortify_memcpy_chk(__kernel_size_t size,
486488
*/
487489

488490
/*
489-
* __builtin_object_size() must be captured here to avoid evaluating argument
490-
* side-effects further into the macro layers.
491+
* __struct_size() vs __member_size() must be captured here to avoid
492+
* evaluating argument side-effects further into the macro layers.
491493
*/
492494
#define memcpy(p, q, s) __fortify_memcpy_chk(p, q, s, \
493-
__builtin_object_size(p, 0), __builtin_object_size(q, 0), \
494-
__builtin_object_size(p, 1), __builtin_object_size(q, 1), \
495+
__struct_size(p), __struct_size(q), \
496+
__member_size(p), __member_size(q), \
495497
memcpy)
496498
#define memmove(p, q, s) __fortify_memcpy_chk(p, q, s, \
497-
__builtin_object_size(p, 0), __builtin_object_size(q, 0), \
498-
__builtin_object_size(p, 1), __builtin_object_size(q, 1), \
499+
__struct_size(p), __struct_size(q), \
500+
__member_size(p), __member_size(q), \
499501
memmove)
500502

501503
extern void *__real_memscan(void *, int, __kernel_size_t) __RENAME(memscan);
502504
__FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size)
503505
{
504-
size_t p_size = __builtin_object_size(p, 0);
506+
size_t p_size = __struct_size(p);
505507

506508
if (__compiletime_lessthan(p_size, size))
507509
__read_overflow();
@@ -513,8 +515,8 @@ __FORTIFY_INLINE void *memscan(void * const POS0 p, int c, __kernel_size_t size)
513515
__FORTIFY_INLINE __diagnose_as(__builtin_memcmp, 1, 2, 3)
514516
int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t size)
515517
{
516-
size_t p_size = __builtin_object_size(p, 0);
517-
size_t q_size = __builtin_object_size(q, 0);
518+
size_t p_size = __struct_size(p);
519+
size_t q_size = __struct_size(q);
518520

519521
if (__builtin_constant_p(size)) {
520522
if (__compiletime_lessthan(p_size, size))
@@ -530,7 +532,7 @@ int memcmp(const void * const POS0 p, const void * const POS0 q, __kernel_size_t
530532
__FORTIFY_INLINE __diagnose_as(__builtin_memchr, 1, 2, 3)
531533
void *memchr(const void * const POS0 p, int c, __kernel_size_t size)
532534
{
533-
size_t p_size = __builtin_object_size(p, 0);
535+
size_t p_size = __struct_size(p);
534536

535537
if (__compiletime_lessthan(p_size, size))
536538
__read_overflow();
@@ -542,7 +544,7 @@ void *memchr(const void * const POS0 p, int c, __kernel_size_t size)
542544
void *__real_memchr_inv(const void *s, int c, size_t n) __RENAME(memchr_inv);
543545
__FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size)
544546
{
545-
size_t p_size = __builtin_object_size(p, 0);
547+
size_t p_size = __struct_size(p);
546548

547549
if (__compiletime_lessthan(p_size, size))
548550
__read_overflow();
@@ -554,7 +556,7 @@ __FORTIFY_INLINE void *memchr_inv(const void * const POS0 p, int c, size_t size)
554556
extern void *__real_kmemdup(const void *src, size_t len, gfp_t gfp) __RENAME(kmemdup);
555557
__FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp)
556558
{
557-
size_t p_size = __builtin_object_size(p, 0);
559+
size_t p_size = __struct_size(p);
558560

559561
if (__compiletime_lessthan(p_size, size))
560562
__read_overflow();
@@ -567,8 +569,8 @@ __FORTIFY_INLINE void *kmemdup(const void * const POS0 p, size_t size, gfp_t gfp
567569
__FORTIFY_INLINE __diagnose_as(__builtin_strcpy, 1, 2)
568570
char *strcpy(char * const POS p, const char * const POS q)
569571
{
570-
size_t p_size = __builtin_object_size(p, 1);
571-
size_t q_size = __builtin_object_size(q, 1);
572+
size_t p_size = __member_size(p);
573+
size_t q_size = __member_size(q);
572574
size_t size;
573575

574576
/* If neither buffer size is known, immediately give up. */

0 commit comments

Comments
 (0)