summaryrefslogtreecommitdiff
path: root/include/string.h
diff options
context:
space:
mode:
authorsin2015-01-29 12:42:41 +0000
committersin2015-01-29 12:42:41 +0000
commit474f2887ce756bb5a14defb25e67b89678be0b8c (patch)
tree6f7995df7890c937aeca36ecfc3dd38e06febdd9 /include/string.h
parent3effc6dacea8b8ed0edab8ad93a902fa05bafde2 (diff)
Add compile-time checks as well
Diffstat (limited to '')
-rw-r--r--include/string.h38
1 files changed, 38 insertions, 0 deletions
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);