summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsin2015-01-29 12:42:41 +0000
committersin2015-01-29 12:42:41 +0000
commit474f2887ce756bb5a14defb25e67b89678be0b8c (patch)
tree6f7995df7890c937aeca36ecfc3dd38e06febdd9
parent3effc6dacea8b8ed0edab8ad93a902fa05bafde2 (diff)
Add compile-time checks as well
-rw-r--r--include/stdio.h16
-rw-r--r--include/string.h38
-rw-r--r--include/strings.h10
3 files changed, 63 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
diff --git a/include/string.h b/include/string.h
index 107df9b..e464eab 100644
--- a/include/string.h
+++ b/include/string.h
@@ -6,6 +6,9 @@
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(__memcpy_error, "memcpy: buffer overflow detected");
9static inline __attribute__ ((always_inline)) 12static inline __attribute__ ((always_inline))
10void * 13void *
11__fortify_memcpy(void *__restrict dest, const void *__restrict src, size_t n) 14__fortify_memcpy(void *__restrict dest, const void *__restrict src, size_t n)
@@ -14,6 +17,9 @@ __fortify_memcpy(void *__restrict dest, const void *__restrict src, size_t n)
14 char *d = dest; 17 char *d = dest;
15 const char *s = src; 18 const char *s = src;
16 19
20 if (__builtin_constant_p(n) && n > bos)
21 __memcpy_error();
22
17 /* trap if pointers are overlapping */ 23 /* trap if pointers are overlapping */
18 if ((d <= s && d + n > s) || 24 if ((d <= s && d + n > s) ||
19 (s <= d && s + n > d)) 25 (s <= d && s + n > d))
@@ -23,23 +29,31 @@ __fortify_memcpy(void *__restrict dest, const void *__restrict src, size_t n)
23 return memcpy(dest, src, n); 29 return memcpy(dest, src, n);
24} 30}
25 31
32__errordecl(__memmove_error, "memmove: buffer overflow detected");
26static inline __attribute__ ((always_inline)) 33static inline __attribute__ ((always_inline))
27void * 34void *
28__fortify_memmove(void *__restrict dest, const void *__restrict src, size_t n) 35__fortify_memmove(void *__restrict dest, const void *__restrict src, size_t n)
29{ 36{
30 size_t bos = __builtin_object_size(dest, 0); 37 size_t bos = __builtin_object_size(dest, 0);
31 38
39 if (__builtin_constant_p(n) && n > bos)
40 __memmove_error();
41
32 if (n > bos) 42 if (n > bos)
33 __builtin_trap(); 43 __builtin_trap();
34 return memmove(dest, src, n); 44 return memmove(dest, src, n);
35} 45}
36 46
47__errordecl(__memset_error, "memset: buffer overflow detected");
37static inline __attribute__ ((always_inline)) 48static inline __attribute__ ((always_inline))
38void * 49void *
39__fortify_memset(void *dest, int c, size_t n) 50__fortify_memset(void *dest, int c, size_t n)
40{ 51{
41 size_t bos = __builtin_object_size(dest, 0); 52 size_t bos = __builtin_object_size(dest, 0);
42 53
54 if (__builtin_constant_p(n) && n > bos)
55 __memset_error();
56
43 if (n > bos) 57 if (n > bos)
44 __builtin_trap(); 58 __builtin_trap();
45 return memset(dest, c, n); 59 return memset(dest, c, n);
@@ -56,12 +70,16 @@ __fortify_stpcpy(char *__restrict dest, const char *__restrict src)
56 return stpcpy(dest, src); 70 return stpcpy(dest, src);
57} 71}
58 72
73__errordecl(__stpncpy_error, "stpncpy: buffer overflow detected");
59static inline __attribute__ ((always_inline)) 74static inline __attribute__ ((always_inline))
60char * 75char *
61__fortify_stpncpy(char *__restrict dest, const char *__restrict src, size_t n) 76__fortify_stpncpy(char *__restrict dest, const char *__restrict src, size_t n)
62{ 77{
63 size_t bos = __builtin_object_size(dest, 0); 78 size_t bos = __builtin_object_size(dest, 0);
64 79
80 if (__builtin_costant_p(n) && n > bos)
81 __stpncpy_error();
82
65 if (n > bos) 83 if (n > bos)
66 __builtin_trap(); 84 __builtin_trap();
67 return stpncpy(dest, src, n); 85 return stpncpy(dest, src, n);
@@ -89,6 +107,7 @@ __fortify_strcpy(char *__restrict dest, const char *__restrict src)
89 return strcpy(dest, src); 107 return strcpy(dest, src);
90} 108}
91 109
110__errordecl(__strncat_error, "strncat: buffer overflow detected");
92static inline __attribute__ ((always_inline)) 111static inline __attribute__ ((always_inline))
93char * 112char *
94__fortify_strncat(char *__restrict dest, const char *__restrict src, size_t n) 113__fortify_strncat(char *__restrict dest, const char *__restrict src, size_t n)
@@ -96,6 +115,9 @@ __fortify_strncat(char *__restrict dest, const char *__restrict src, size_t n)
96 size_t bos = __builtin_object_size(dest, 0); 115 size_t bos = __builtin_object_size(dest, 0);
97 size_t slen, dlen; 116 size_t slen, dlen;
98 117
118 if (__builtin_constant_p(n) && n > bos)
119 __strncat_error();
120
99 if (n > bos) { 121 if (n > bos) {
100 slen = strlen(src); 122 slen = strlen(src);
101 dlen = strlen(dest); 123 dlen = strlen(dest);
@@ -107,24 +129,32 @@ __fortify_strncat(char *__restrict dest, const char *__restrict src, size_t n)
107 return strncat(dest, src, n); 129 return strncat(dest, src, n);
108} 130}
109 131
132__errordecl(__strncpy_error, "strncpy: buffer overflow detected");
110static inline __attribute__ ((always_inline)) 133static inline __attribute__ ((always_inline))
111char * 134char *
112__fortify_strncpy(char *__restrict dest, const char *__restrict src, size_t n) 135__fortify_strncpy(char *__restrict dest, const char *__restrict src, size_t n)
113{ 136{
114 size_t bos = __builtin_object_size(dest, 0); 137 size_t bos = __builtin_object_size(dest, 0);
115 138
139 if (__builtin_constant_p(n) && n > bos)
140 __strncpy_error();
141
116 if (n > bos) 142 if (n > bos)
117 __builtin_trap(); 143 __builtin_trap();
118 return strncpy(dest, src, n); 144 return strncpy(dest, src, n);
119} 145}
120 146
121#ifdef _GNU_SOURCE 147#ifdef _GNU_SOURCE
148__errordecl(__mempcpy_error, "mempcpy: buffer overflow detected");
122static inline __attribute__ ((always_inline)) 149static inline __attribute__ ((always_inline))
123void * 150void *
124__fortify_mempcpy(void *__restrict dest, const void *__restrict src, size_t n) 151__fortify_mempcpy(void *__restrict dest, const void *__restrict src, size_t n)
125{ 152{
126 size_t bos = __builtin_object_size(dest, 0); 153 size_t bos = __builtin_object_size(dest, 0);
127 154
155 if (__builtin_constant_p(n) && n > bos)
156 __mempcpy_error();
157
128 if (n > bos) 158 if (n > bos)
129 __builtin_trap(); 159 __builtin_trap();
130 return mempcpy(dest, src, n); 160 return mempcpy(dest, src, n);
@@ -132,23 +162,31 @@ __fortify_mempcpy(void *__restrict dest, const void *__restrict src, size_t n)
132#endif 162#endif
133 163
134#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) 164#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE)
165__errordecl(__strlcat_error, "strlcat: buffer overflow detected");
135static inline __attribute__ ((always_inline)) 166static inline __attribute__ ((always_inline))
136size_t 167size_t
137__fortify_strlcat(char *__restrict dest, const char *__restrict src, size_t n) 168__fortify_strlcat(char *__restrict dest, const char *__restrict src, size_t n)
138{ 169{
139 size_t bos = __builtin_object_size(dest, 0); 170 size_t bos = __builtin_object_size(dest, 0);
140 171
172 if (__builtin_constant_p(n) && n > bos)
173 __strlcat_error();
174
141 if (n > bos) 175 if (n > bos)
142 __builtin_trap(); 176 __builtin_trap();
143 return strlcat(dest, src, n); 177 return strlcat(dest, src, n);
144} 178}
145 179
180__errordecl(__strlcpy_error, "strlcpy: buffer overflow detected");
146static inline __attribute__ ((always_inline)) 181static inline __attribute__ ((always_inline))
147size_t 182size_t
148__fortify_strlcpy(char *__restrict dest, const char *__restrict src, size_t n) 183__fortify_strlcpy(char *__restrict dest, const char *__restrict src, size_t n)
149{ 184{
150 size_t bos = __builtin_object_size(dest, 0); 185 size_t bos = __builtin_object_size(dest, 0);
151 186
187 if (__builtin_constant_p(n) && n > bos)
188 __strlcpy_error();
189
152 if (n > bos) 190 if (n > bos)
153 __builtin_trap(); 191 __builtin_trap();
154 return strlcpy(dest, src, n); 192 return strlcpy(dest, src, n);
diff --git a/include/strings.h b/include/strings.h
index c2f3bcd..4086fe4 100644
--- a/include/strings.h
+++ b/include/strings.h
@@ -6,26 +6,36 @@
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
9#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \ 11#if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) || defined(_POSIX_SOURCE) \
10 || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \ 12 || (defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE+0 < 200809L) \
11 || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700) 13 || (defined(_XOPEN_SOURCE) && _XOPEN_SOURCE+0 < 700)
14__errordecl(__bcopy_error, "bcopy: buffer overflow detected");
12static inline __attribute__ ((always_inline)) 15static inline __attribute__ ((always_inline))
13void 16void
14__fortify_bcopy(const void *__restrict src, void *__restrict dest, size_t n) 17__fortify_bcopy(const void *__restrict src, void *__restrict dest, size_t n)
15{ 18{
16 size_t bos = __builtin_object_size(dest, 0); 19 size_t bos = __builtin_object_size(dest, 0);
17 20
21 if (__builtin_constant_p(n) && n > bos)
22 __bcopy_error();
23
18 if (n > bos) 24 if (n > bos)
19 __builtin_trap(); 25 __builtin_trap();
20 return bcopy(src, dest, n); 26 return bcopy(src, dest, n);
21} 27}
22 28
29__errordecl(__bzero_error, "bzero: buffer overflow detected");
23static inline __attribute__ ((always_inline)) 30static inline __attribute__ ((always_inline))
24void 31void
25__fortify_bzero(void *src, size_t n) 32__fortify_bzero(void *src, size_t n)
26{ 33{
27 size_t bos = __builtin_object_size(src, 0); 34 size_t bos = __builtin_object_size(src, 0);
28 35
36 if (__builtin_constant_p(n) && n > bos)
37 __bzero_error();
38
29 if (n > bos) 39 if (n > bos)
30 __builtin_trap(); 40 __builtin_trap();
31 return bzero(src, n); 41 return bzero(src, n);