1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29 #ifndef _STRING_H
30 #error "Never include this file directly; instead, include <string.h>"
31 #endif
32
33 void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
34 void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
35 char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
36 char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
37 size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
38 size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
39
40 #if defined(__BIONIC_FORTIFY)
41 extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
42
43 // These can share their implementation between gcc and clang with minimal
44 // trickery...
45 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
46 __BIONIC_FORTIFY_INLINE
memcpy(void * const dst __pass_object_size0,const void * src,size_t copy_amount)47 void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
48 __overloadable
49 __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount,
50 "'memcpy' called with size bigger than buffer") {
51 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
52 }
53
54 __BIONIC_FORTIFY_INLINE
memmove(void * const dst __pass_object_size0,const void * src,size_t len)55 void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
56 __overloadable
57 __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len,
58 "'memmove' called with size bigger than buffer") {
59 return __builtin___memmove_chk(dst, src, len, __bos0(dst));
60 }
61 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
62
63 #if __ANDROID_API__ >= __ANDROID_API_L__
64 __BIONIC_FORTIFY_INLINE
stpcpy(char * const dst __pass_object_size,const char * src)65 char* stpcpy(char* const dst __pass_object_size, const char* src)
66 __overloadable
67 __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
68 __bos(dst) <= __builtin_strlen(src),
69 "'stpcpy' called with string bigger than buffer") {
70 return __builtin___stpcpy_chk(dst, src, __bos(dst));
71 }
72 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
73
74 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
75 __BIONIC_FORTIFY_INLINE
strcpy(char * const dst __pass_object_size,const char * src)76 char* strcpy(char* const dst __pass_object_size, const char* src)
77 __overloadable
78 __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
79 __bos(dst) <= __builtin_strlen(src),
80 "'strcpy' called with string bigger than buffer") {
81 return __builtin___strcpy_chk(dst, src, __bos(dst));
82 }
83
84 __BIONIC_FORTIFY_INLINE
strcat(char * const dst __pass_object_size,const char * src)85 char* strcat(char* const dst __pass_object_size, const char* src) __overloadable {
86 return __builtin___strcat_chk(dst, src, __bos(dst));
87 }
88
89 __BIONIC_FORTIFY_INLINE
strncat(char * const dst __pass_object_size,const char * src,size_t n)90 char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
91 return __builtin___strncat_chk(dst, src, n, __bos(dst));
92 }
93
94 __BIONIC_FORTIFY_INLINE
memset(void * const s __pass_object_size0,int c,size_t n)95 void* memset(void* const s __pass_object_size0, int c, size_t n)
96 __overloadable
97 __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n,
98 "'memset' called with size bigger than buffer")
99 /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
100 __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
101 return __builtin___memset_chk(s, c, n, __bos0(s));
102 }
103 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
104
105
106 #if defined(__clang__)
107
108 #if __ANDROID_API__ >= __ANDROID_API_M__
109 __BIONIC_FORTIFY_INLINE
memchr(const void * const s __pass_object_size,int c,size_t n)110 void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
111 size_t bos = __bos(s);
112
113 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
114 return __builtin_memchr(s, c, n);
115 }
116
117 return __memchr_chk(s, c, n, bos);
118 }
119
120 __BIONIC_FORTIFY_INLINE
__memrchr_fortify(const void * const __pass_object_size s,int c,size_t n)121 void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
122 size_t bos = __bos(s);
123
124 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
125 return __memrchr_real(s, c, n);
126 }
127
128 return __memrchr_chk(s, c, n, bos);
129 }
130 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
131
132 #if __ANDROID_API__ >= __ANDROID_API_L__
133 __BIONIC_FORTIFY_INLINE
stpncpy(char * const dst __pass_object_size,const char * const src __pass_object_size,size_t n)134 char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
135 __overloadable {
136 size_t bos_dst = __bos(dst);
137 size_t bos_src = __bos(src);
138
139 /* Ignore dst size checks; they're handled in strncpy_chk */
140 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
141 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
142 }
143
144 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
145 }
146
147 __BIONIC_FORTIFY_INLINE
strncpy(char * const dst __pass_object_size,const char * const src __pass_object_size,size_t n)148 char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
149 __overloadable {
150 size_t bos_dst = __bos(dst);
151 size_t bos_src = __bos(src);
152
153 /* Ignore dst size checks; they're handled in strncpy_chk */
154 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
155 return __builtin___strncpy_chk(dst, src, n, bos_dst);
156 }
157
158 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
159 }
160 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
161
162 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
163 __BIONIC_FORTIFY_INLINE
strlcpy(char * const dst __pass_object_size,const char * src,size_t size)164 size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
165 size_t bos = __bos(dst);
166
167 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
168 return __call_bypassing_fortify(strlcpy)(dst, src, size);
169 }
170
171 return __strlcpy_chk(dst, src, size, bos);
172 }
173
174 __BIONIC_FORTIFY_INLINE
strlcat(char * const dst __pass_object_size,const char * src,size_t size)175 size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
176 size_t bos = __bos(dst);
177
178 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
179 return __call_bypassing_fortify(strlcat)(dst, src, size);
180 }
181
182 return __strlcat_chk(dst, src, size, bos);
183 }
184
185 /*
186 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
187 * on it directly. This makes it way easier for compilers to fold things like
188 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
189 * because it's large.
190 */
191 __BIONIC_FORTIFY_INLINE
strlen(const char * const s __pass_object_size)192 size_t strlen(const char* const s __pass_object_size)
193 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
194 "enabled if s is a known good string.") {
195 return __builtin_strlen(s);
196 }
197
198 __BIONIC_FORTIFY_INLINE
strlen(const char * const s __pass_object_size0)199 size_t strlen(const char* const s __pass_object_size0) __overloadable {
200 size_t bos = __bos0(s);
201
202 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
203 return __builtin_strlen(s);
204 }
205
206 return __strlen_chk(s, bos);
207 }
208 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
209
210 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
211 __BIONIC_FORTIFY_INLINE
strchr(const char * const s __pass_object_size,int c)212 char* strchr(const char* const s __pass_object_size, int c) __overloadable {
213 size_t bos = __bos(s);
214
215 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
216 return __builtin_strchr(s, c);
217 }
218
219 return __strchr_chk(s, c, bos);
220 }
221
222 __BIONIC_FORTIFY_INLINE
strrchr(const char * const s __pass_object_size,int c)223 char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
224 size_t bos = __bos(s);
225
226 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
227 return __builtin_strrchr(s, c);
228 }
229
230 return __strrchr_chk(s, c, bos);
231 }
232 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
233
234 #else // defined(__clang__)
235 extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
236 extern size_t __strlcpy_real(char*, const char*, size_t)
237 __RENAME(strlcpy);
238 extern size_t __strlcat_real(char*, const char*, size_t)
239 __RENAME(strlcat);
240
241 __errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
242 __errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
243
244 #if __ANDROID_API__ >= __ANDROID_API_M__
245 __BIONIC_FORTIFY_INLINE
memchr(const void * s __pass_object_size,int c,size_t n)246 void* memchr(const void* s __pass_object_size, int c, size_t n) {
247 size_t bos = __bos(s);
248
249 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
250 return __builtin_memchr(s, c, n);
251 }
252
253 if (__builtin_constant_p(n) && (n > bos)) {
254 __memchr_buf_size_error();
255 }
256
257 if (__builtin_constant_p(n) && (n <= bos)) {
258 return __builtin_memchr(s, c, n);
259 }
260
261 return __memchr_chk(s, c, n, bos);
262 }
263
264 __BIONIC_FORTIFY_INLINE
__memrchr_fortify(const void * s,int c,size_t n)265 void* __memrchr_fortify(const void* s, int c, size_t n) {
266 size_t bos = __bos(s);
267
268 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
269 return __memrchr_real(s, c, n);
270 }
271
272 if (__builtin_constant_p(n) && (n > bos)) {
273 __memrchr_buf_size_error();
274 }
275
276 if (__builtin_constant_p(n) && (n <= bos)) {
277 return __memrchr_real(s, c, n);
278 }
279
280 return __memrchr_chk(s, c, n, bos);
281 }
282 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
283
284 #if __ANDROID_API__ >= __ANDROID_API_L__
285 __BIONIC_FORTIFY_INLINE
stpncpy(char * dst,const char * src,size_t n)286 char* stpncpy(char* dst, const char* src, size_t n) {
287 size_t bos_dst = __bos(dst);
288 size_t bos_src = __bos(src);
289
290 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
291 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
292 }
293
294 if (__builtin_constant_p(n) && (n <= bos_src)) {
295 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
296 }
297
298 size_t slen = __builtin_strlen(src);
299 if (__builtin_constant_p(slen)) {
300 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
301 }
302
303 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
304 }
305
306 __BIONIC_FORTIFY_INLINE
strncpy(char * dst,const char * src,size_t n)307 char* strncpy(char* dst, const char* src, size_t n) {
308 size_t bos_dst = __bos(dst);
309 size_t bos_src = __bos(src);
310
311 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
312 return __strncpy_real(dst, src, n);
313 }
314
315 if (__builtin_constant_p(n) && (n <= bos_src)) {
316 return __builtin___strncpy_chk(dst, src, n, bos_dst);
317 }
318
319 size_t slen = __builtin_strlen(src);
320 if (__builtin_constant_p(slen)) {
321 return __builtin___strncpy_chk(dst, src, n, bos_dst);
322 }
323
324 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
325 }
326 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
327
328 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
329 __BIONIC_FORTIFY_INLINE
strlcpy(char * dst __pass_object_size,const char * src,size_t size)330 size_t strlcpy(char* dst __pass_object_size, const char* src, size_t size) {
331 size_t bos = __bos(dst);
332
333 // Compiler doesn't know destination size. Don't call __strlcpy_chk
334 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
335 return __strlcpy_real(dst, src, size);
336 }
337
338 // Compiler can prove, at compile time, that the passed in size
339 // is always <= the actual object size. Don't call __strlcpy_chk
340 if (__builtin_constant_p(size) && (size <= bos)) {
341 return __strlcpy_real(dst, src, size);
342 }
343
344 return __strlcpy_chk(dst, src, size, bos);
345 }
346
347 __BIONIC_FORTIFY_INLINE
strlcat(char * dst,const char * src,size_t size)348 size_t strlcat(char* dst, const char* src, size_t size) {
349 size_t bos = __bos(dst);
350
351 // Compiler doesn't know destination size. Don't call __strlcat_chk
352 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
353 return __strlcat_real(dst, src, size);
354 }
355
356 // Compiler can prove, at compile time, that the passed in size
357 // is always <= the actual object size. Don't call __strlcat_chk
358 if (__builtin_constant_p(size) && (size <= bos)) {
359 return __strlcat_real(dst, src, size);
360 }
361
362 return __strlcat_chk(dst, src, size, bos);
363 }
364
365 __BIONIC_FORTIFY_INLINE
strlen(const char * s)366 size_t strlen(const char* s) __overloadable {
367 size_t bos = __bos(s);
368
369 // Compiler doesn't know destination size. Don't call __strlen_chk
370 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
371 return __builtin_strlen(s);
372 }
373
374 size_t slen = __builtin_strlen(s);
375 if (__builtin_constant_p(slen)) {
376 return slen;
377 }
378
379 return __strlen_chk(s, bos);
380 }
381 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
382
383 #if __ANDROID_API__ >= __ANDROID_API_J_MR2__
384 __BIONIC_FORTIFY_INLINE
strchr(const char * s,int c)385 char* strchr(const char* s, int c) {
386 size_t bos = __bos(s);
387
388 // Compiler doesn't know destination size. Don't call __strchr_chk
389 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
390 return __builtin_strchr(s, c);
391 }
392
393 size_t slen = __builtin_strlen(s);
394 if (__builtin_constant_p(slen) && (slen < bos)) {
395 return __builtin_strchr(s, c);
396 }
397
398 return __strchr_chk(s, c, bos);
399 }
400
401 __BIONIC_FORTIFY_INLINE
strrchr(const char * s,int c)402 char* strrchr(const char* s, int c) {
403 size_t bos = __bos(s);
404
405 // Compiler doesn't know destination size. Don't call __strrchr_chk
406 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
407 return __builtin_strrchr(s, c);
408 }
409
410 size_t slen = __builtin_strlen(s);
411 if (__builtin_constant_p(slen) && (slen < bos)) {
412 return __builtin_strrchr(s, c);
413 }
414
415 return __strrchr_chk(s, c, bos);
416 }
417 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
418 #endif /* defined(__clang__) */
419
420 #if __ANDROID_API__ >= __ANDROID_API_M__
421 #if defined(__cplusplus)
422 extern "C++" {
423 __BIONIC_FORTIFY_INLINE
memrchr(void * const __pass_object_size s,int c,size_t n)424 void* memrchr(void* const __pass_object_size s, int c, size_t n) {
425 return __memrchr_fortify(s, c, n);
426 }
427
428 __BIONIC_FORTIFY_INLINE
memrchr(const void * const __pass_object_size s,int c,size_t n)429 const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
430 return __memrchr_fortify(s, c, n);
431 }
432 }
433 #else
434 __BIONIC_FORTIFY_INLINE
memrchr(const void * const __pass_object_size s,int c,size_t n)435 void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
436 return __memrchr_fortify(s, c, n);
437 }
438 #endif
439 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
440
441 #endif /* defined(__BIONIC_FORTIFY) */
442