diff options
Diffstat (limited to 'include/stdio.h')
| -rw-r--r-- | include/stdio.h | 16 |
1 files changed, 15 insertions, 1 deletions
diff --git a/include/stdio.h b/include/stdio.h index 070d4e5..285fe21 100644 --- a/include/stdio.h +++ b/include/stdio.h | |||
| @@ -6,17 +6,24 @@ | |||
| 6 | 6 | ||
| 7 | #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 | 7 | #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 |
| 8 | 8 | ||
| 9 | #define __errordecl(name, msg) extern void name(void) __attribute__((__error__(msg))) | ||
| 10 | |||
| 11 | __errordecl(__fgets_error, "fgets: buffer overflow detected"); | ||
| 9 | static inline __attribute__ ((always_inline)) | 12 | static inline __attribute__ ((always_inline)) |
| 10 | char * | 13 | char * |
| 11 | __fortify_fgets(char *s, int n, FILE *fp) | 14 | __fortify_fgets(char *s, int n, FILE *fp) |
| 12 | { | 15 | { |
| 13 | size_t bos = __builtin_object_size(s, 0); | 16 | size_t bos = __builtin_object_size(s, 0); |
| 14 | 17 | ||
| 18 | if (__builtin_constant_p(n) && (size_t)n > bos) | ||
| 19 | __fgets_error(); | ||
| 20 | |||
| 15 | if ((size_t)n > bos) | 21 | if ((size_t)n > bos) |
| 16 | __builtin_trap(); | 22 | __builtin_trap(); |
| 17 | return fgets(s, n, fp); | 23 | return fgets(s, n, fp); |
| 18 | } | 24 | } |
| 19 | 25 | ||
| 26 | __errordecl(__vsnprintf_error, "vsnprintf: buffer overflow detected"); | ||
| 20 | static inline | 27 | static inline |
| 21 | __attribute__ ((always_inline)) | 28 | __attribute__ ((always_inline)) |
| 22 | __attribute__ ((__format__ (printf, 3, 0))) | 29 | __attribute__ ((__format__ (printf, 3, 0))) |
| @@ -27,6 +34,9 @@ __fortify_vsnprintf(char *__restrict s, size_t n, const char *__restrict fmt, | |||
| 27 | { | 34 | { |
| 28 | size_t bos = __builtin_object_size(s, 0); | 35 | size_t bos = __builtin_object_size(s, 0); |
| 29 | 36 | ||
| 37 | if (__builtin_constant_p(n) && n > bos) | ||
| 38 | __vsnprintf_error(); | ||
| 39 | |||
| 30 | if (n > bos) | 40 | if (n > bos) |
| 31 | __builtin_trap(); | 41 | __builtin_trap(); |
| 32 | return vsnprintf(s, n, fmt, ap); | 42 | return vsnprintf(s, n, fmt, ap); |
| @@ -36,13 +46,17 @@ __fortify_vsnprintf(char *__restrict s, size_t n, const char *__restrict fmt, | |||
| 36 | #define fgets(s, n, fp) __fortify_fgets(s, n, fp) | 46 | #define fgets(s, n, fp) __fortify_fgets(s, n, fp) |
| 37 | #undef vsnprintf | 47 | #undef vsnprintf |
| 38 | #define vsnprintf(s, n, fmt, ap) __fortify_vsnprintf(s, n, fmt, ap) | 48 | #define vsnprintf(s, n, fmt, ap) __fortify_vsnprintf(s, n, fmt, ap) |
| 49 | |||
| 50 | __errordecl(__snprintf_error, "snprintf: buffer overflow detected"); | ||
| 39 | #undef snprintf | 51 | #undef snprintf |
| 40 | #define snprintf(s, n, fmt, ...) ({ \ | 52 | #define snprintf(s, n, fmt, ...) ({ \ |
| 41 | size_t _n = (n); \ | 53 | size_t _n = (n); \ |
| 42 | size_t bos = __builtin_object_size(s, 0); \ | 54 | size_t bos = __builtin_object_size(s, 0); \ |
| 55 | if (__builtin_constant_p(_n) && _n > bos) \ | ||
| 56 | __snprintf_error(); \ | ||
| 43 | if (_n > bos) \ | 57 | if (_n > bos) \ |
| 44 | __builtin_trap(); \ | 58 | __builtin_trap(); \ |
| 45 | snprintf(s, _n, fmt, __VA_ARGS__); \ | 59 | snprintf(s, _n, fmt, ## __VA_ARGS__); \ |
| 46 | }) | 60 | }) |
| 47 | 61 | ||
| 48 | #endif | 62 | #endif |
