summaryrefslogtreecommitdiff
path: root/include/stdio.h
diff options
context:
space:
mode:
authorsin2015-01-29 12:42:41 +0000
committersin2015-01-29 12:42:41 +0000
commit474f2887ce756bb5a14defb25e67b89678be0b8c (patch)
tree6f7995df7890c937aeca36ecfc3dd38e06febdd9 /include/stdio.h
parent3effc6dacea8b8ed0edab8ad93a902fa05bafde2 (diff)
Add compile-time checks as well
Diffstat (limited to 'include/stdio.h')
-rw-r--r--include/stdio.h16
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");
9static inline __attribute__ ((always_inline)) 12static inline __attribute__ ((always_inline))
10char * 13char *
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");
20static inline 27static 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