blob: 74e87a42a75695462e83d690ac2f3c154fd10045 [file] [log] [blame]
George Burgess IVb97049c2017-07-24 15:05:05 -07001/*
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
33void* __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
34void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
35char* __stpncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
36 __INTRODUCED_IN(21);
37char* __strncpy_chk2(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t, size_t)
38 __INTRODUCED_IN(21);
39size_t __strlcpy_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
40size_t __strlcat_chk(char* _Nonnull __restrict, const char* _Nonnull __restrict, size_t, size_t) __INTRODUCED_IN(17);
41
42/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we
43 * have the definition out here.
44 */
45struct __bionic_zero_size_is_okay_t {};
46
47#if defined(__BIONIC_FORTIFY)
48// These can share their implementation between gcc and clang with minimal
49// trickery...
50#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
51__BIONIC_FORTIFY_INLINE
52void* memcpy(void* _Nonnull __restrict const dst __pass_object_size0, const void* _Nonnull __restrict src, size_t copy_amount)
53 __overloadable {
54 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
55}
56
57__BIONIC_FORTIFY_INLINE
58void* memmove(void* const _Nonnull dst __pass_object_size0, const void* _Nonnull src, size_t len)
59 __overloadable {
60 return __builtin___memmove_chk(dst, src, len, __bos0(dst));
61}
62#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
63
64#if __ANDROID_API__ >= __ANDROID_API_L__
65__BIONIC_FORTIFY_INLINE
66char* stpcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
67 __overloadable {
68 return __builtin___stpcpy_chk(dst, src, __bos(dst));
69}
70#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
71
72#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
73__BIONIC_FORTIFY_INLINE
74char* strcpy(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
75 __overloadable {
76 return __builtin___strcpy_chk(dst, src, __bos(dst));
77}
78
79__BIONIC_FORTIFY_INLINE
80char* strcat(char* _Nonnull __restrict const dst __pass_object_size, const char* _Nonnull __restrict src)
81 __overloadable {
82 return __builtin___strcat_chk(dst, src, __bos(dst));
83}
84
85__BIONIC_FORTIFY_INLINE
86char* strncat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t n)
87 __overloadable {
88 return __builtin___strncat_chk(dst, src, n, __bos(dst));
89}
90
91__BIONIC_FORTIFY_INLINE
92void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n) __overloadable {
93 return __builtin___memset_chk(s, c, n, __bos0(s));
94}
95#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
96
97
98#if defined(__clang__)
99
100#define __error_if_overflows_dst(name, dst, n, what) \
101 __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \
102 __bos0(dst) < (n), "selected when the buffer is too small") \
103 __errorattr(#name " called with " what " bigger than buffer")
104
105/*
106 * N.B. _Nonnull isn't necessary on params, since these functions just emit
107 * errors.
108 */
109__BIONIC_ERROR_FUNCTION_VISIBILITY
110void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable
111 __error_if_overflows_dst(memcpy, dst, copy_amount, "size");
112
113__BIONIC_ERROR_FUNCTION_VISIBILITY
114void* memmove(void *dst, const void* src, size_t len) __overloadable
115 __error_if_overflows_dst(memmove, dst, len, "size");
116
117__BIONIC_ERROR_FUNCTION_VISIBILITY
118void* memset(void* s, int c, size_t n) __overloadable
119 __error_if_overflows_dst(memset, s, n, "size");
120
121__BIONIC_ERROR_FUNCTION_VISIBILITY
122char* stpcpy(char* dst, const char* src) __overloadable
123 __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string");
124
125__BIONIC_ERROR_FUNCTION_VISIBILITY
126char* strcpy(char* dst, const char* src) __overloadable
127 __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string");
128
129#if __ANDROID_API__ >= __ANDROID_API_M__
130__BIONIC_FORTIFY_INLINE
131void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
132 __overloadable {
133 size_t bos = __bos(s);
134
135 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
136 return __builtin_memchr(s, c, n);
137 }
138
139 return __memchr_chk(s, c, n, bos);
140}
141
142__BIONIC_FORTIFY_INLINE
143void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n)
144 __overloadable {
145 size_t bos = __bos(s);
146
147 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
148 return __call_bypassing_fortify(memrchr)(s, c, n);
149 }
150
151 return __memrchr_chk(s, c, n, bos);
152}
153#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
154
155#if __ANDROID_API__ >= __ANDROID_API_L__
156__BIONIC_FORTIFY_INLINE
157char* stpncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
158 __overloadable {
159 size_t bos_dst = __bos(dst);
160 size_t bos_src = __bos(src);
161
162 /* Ignore dst size checks; they're handled in strncpy_chk */
163 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
164 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
165 }
166
167 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
168}
169
170__BIONIC_FORTIFY_INLINE
171char* strncpy(char* __restrict const _Nonnull dst __pass_object_size, const char* __restrict const _Nonnull src __pass_object_size, size_t n)
172 __overloadable {
173 size_t bos_dst = __bos(dst);
174 size_t bos_src = __bos(src);
175
176 /* Ignore dst size checks; they're handled in strncpy_chk */
177 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
178 return __builtin___strncpy_chk(dst, src, n, bos_dst);
179 }
180
181 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
182}
183#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
184
185#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
186__BIONIC_FORTIFY_INLINE
187size_t strlcpy(char* const _Nonnull __restrict dst __pass_object_size, const char *_Nonnull __restrict src, size_t size)
188 __overloadable {
189 size_t bos = __bos(dst);
190
191 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
192 return __call_bypassing_fortify(strlcpy)(dst, src, size);
193 }
194
195 return __strlcpy_chk(dst, src, size, bos);
196}
197
198__BIONIC_FORTIFY_INLINE
199size_t strlcat(char* const _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size)
200 __overloadable {
201 size_t bos = __bos(dst);
202
203 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
204 return __call_bypassing_fortify(strlcat)(dst, src, size);
205 }
206
207 return __strlcat_chk(dst, src, size, bos);
208}
209
210/*
211 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
212 * on it directly. This makes it way easier for compilers to fold things like
213 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
214 * because it's large.
215 */
216__BIONIC_FORTIFY_INLINE
217size_t strlen(const char* const _Nonnull s __pass_object_size)
218 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
219 "enabled if s is a known good string.") {
220 return __builtin_strlen(s);
221}
222
223__BIONIC_FORTIFY_INLINE
224size_t strlen(const char* const _Nonnull s __pass_object_size0)
225 __overloadable {
226 size_t bos = __bos0(s);
227
228 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
229 return __builtin_strlen(s);
230 }
231
232 // return __builtin_strlen(s);
233 return __strlen_chk(s, bos);
234}
235#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
236
237#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
238__BIONIC_FORTIFY_INLINE
239char* strchr(const char* const _Nonnull s __pass_object_size, int c)
240 __overloadable {
241 size_t bos = __bos(s);
242
243 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
244 return __builtin_strchr(s, c);
245 }
246
247 return __strchr_chk(s, c, bos);
248}
249
250__BIONIC_FORTIFY_INLINE
251char* strrchr(const char* const _Nonnull s __pass_object_size, int c)
252 __overloadable {
253 size_t bos = __bos(s);
254
255 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
256 return __builtin_strrchr(s, c);
257 }
258
259 return __strrchr_chk(s, c, bos);
260}
261#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
262
263#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
264/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has
265 * flipped the size + value arguments. However, there may be cases (e.g. with
266 * macros) where it's okay for the size to fold to zero. We should warn on this,
267 * but we should also provide a FORTIFY'ed escape hatch.
268 */
269__BIONIC_ERROR_FUNCTION_VISIBILITY
270void* memset(void* _Nonnull s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok)
271 __overloadable
272 __error_if_overflows_dst(memset, s, n, "size");
273
274__BIONIC_FORTIFY_INLINE
275void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused)))
276 __overloadable {
277 return __builtin___memset_chk(s, c, n, __bos0(s));
278}
279
280extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay;
281/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is,
282 * flipping size + count will do nothing.
283 */
284__BIONIC_ERROR_FUNCTION_VISIBILITY
285void* memset(void* _Nonnull s, int c, size_t n) __overloadable
286 __enable_if(c && !n, "selected when we'll set zero bytes")
287 __RENAME_CLANG(memset)
288 __warnattr_real("will set 0 bytes; maybe the arguments got flipped? "
289 "(Add __bionic_zero_size_is_okay as a fourth argument "
290 "to silence this.)");
291#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
292
293#undef __error_zero_size
294#undef __error_if_overflows_dst
295#else // defined(__clang__)
296extern char* __strncpy_real(char* __restrict, const char*, size_t) __RENAME(strncpy);
297extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
298extern size_t __strlcpy_real(char* __restrict, const char* __restrict, size_t)
299 __RENAME(strlcpy);
300extern size_t __strlcat_real(char* __restrict, const char* __restrict, size_t)
301 __RENAME(strlcat);
302
303__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
304__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
305
306#if __ANDROID_API__ >= __ANDROID_API_M__
307__BIONIC_FORTIFY_INLINE
308void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) {
309 size_t bos = __bos(s);
310
311 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
312 return __builtin_memchr(s, c, n);
313 }
314
315 if (__builtin_constant_p(n) && (n > bos)) {
316 __memchr_buf_size_error();
317 }
318
319 if (__builtin_constant_p(n) && (n <= bos)) {
320 return __builtin_memchr(s, c, n);
321 }
322
323 return __memchr_chk(s, c, n, bos);
324}
325
326__BIONIC_FORTIFY_INLINE
327void* memrchr(const void* s, int c, size_t n) {
328 size_t bos = __bos(s);
329
330 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
331 return __memrchr_real(s, c, n);
332 }
333
334 if (__builtin_constant_p(n) && (n > bos)) {
335 __memrchr_buf_size_error();
336 }
337
338 if (__builtin_constant_p(n) && (n <= bos)) {
339 return __memrchr_real(s, c, n);
340 }
341
342 return __memrchr_chk(s, c, n, bos);
343}
344#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
345
346#if __ANDROID_API__ >= __ANDROID_API_L__
347__BIONIC_FORTIFY_INLINE
348char* stpncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
349 size_t bos_dst = __bos(dst);
350 size_t bos_src = __bos(src);
351
352 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
353 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
354 }
355
356 if (__builtin_constant_p(n) && (n <= bos_src)) {
357 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
358 }
359
360 size_t slen = __builtin_strlen(src);
361 if (__builtin_constant_p(slen)) {
362 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
363 }
364
365 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
366}
367
368__BIONIC_FORTIFY_INLINE
369char* strncpy(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t n) {
370 size_t bos_dst = __bos(dst);
371 size_t bos_src = __bos(src);
372
373 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
374 return __strncpy_real(dst, src, n);
375 }
376
377 if (__builtin_constant_p(n) && (n <= bos_src)) {
378 return __builtin___strncpy_chk(dst, src, n, bos_dst);
379 }
380
381 size_t slen = __builtin_strlen(src);
382 if (__builtin_constant_p(slen)) {
383 return __builtin___strncpy_chk(dst, src, n, bos_dst);
384 }
385
386 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
387}
388#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
389
390#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
391__BIONIC_FORTIFY_INLINE
392size_t strlcpy(char* _Nonnull __restrict dst __pass_object_size, const char* _Nonnull __restrict src, size_t size) {
393 size_t bos = __bos(dst);
394
395 // Compiler doesn't know destination size. Don't call __strlcpy_chk
396 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
397 return __strlcpy_real(dst, src, size);
398 }
399
400 // Compiler can prove, at compile time, that the passed in size
401 // is always <= the actual object size. Don't call __strlcpy_chk
402 if (__builtin_constant_p(size) && (size <= bos)) {
403 return __strlcpy_real(dst, src, size);
404 }
405
406 return __strlcpy_chk(dst, src, size, bos);
407}
408
409__BIONIC_FORTIFY_INLINE
410size_t strlcat(char* _Nonnull __restrict dst, const char* _Nonnull __restrict src, size_t size) {
411 size_t bos = __bos(dst);
412
413 // Compiler doesn't know destination size. Don't call __strlcat_chk
414 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
415 return __strlcat_real(dst, src, size);
416 }
417
418 // Compiler can prove, at compile time, that the passed in size
419 // is always <= the actual object size. Don't call __strlcat_chk
420 if (__builtin_constant_p(size) && (size <= bos)) {
421 return __strlcat_real(dst, src, size);
422 }
423
424 return __strlcat_chk(dst, src, size, bos);
425}
426
427__BIONIC_FORTIFY_INLINE
428size_t strlen(const char* _Nonnull s) __overloadable {
429 size_t bos = __bos(s);
430
431 // Compiler doesn't know destination size. Don't call __strlen_chk
432 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
433 return __builtin_strlen(s);
434 }
435
436 size_t slen = __builtin_strlen(s);
437 if (__builtin_constant_p(slen)) {
438 return slen;
439 }
440
441 return __strlen_chk(s, bos);
442}
443#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
444
445#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
446__BIONIC_FORTIFY_INLINE
447char* strchr(const char* _Nonnull s, int c) {
448 size_t bos = __bos(s);
449
450 // Compiler doesn't know destination size. Don't call __strchr_chk
451 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
452 return __builtin_strchr(s, c);
453 }
454
455 size_t slen = __builtin_strlen(s);
456 if (__builtin_constant_p(slen) && (slen < bos)) {
457 return __builtin_strchr(s, c);
458 }
459
460 return __strchr_chk(s, c, bos);
461}
462
463__BIONIC_FORTIFY_INLINE
464char* strrchr(const char* _Nonnull s, int c) {
465 size_t bos = __bos(s);
466
467 // Compiler doesn't know destination size. Don't call __strrchr_chk
468 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
469 return __builtin_strrchr(s, c);
470 }
471
472 size_t slen = __builtin_strlen(s);
473 if (__builtin_constant_p(slen) && (slen < bos)) {
474 return __builtin_strrchr(s, c);
475 }
476
477 return __strrchr_chk(s, c, bos);
478}
479#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
480#endif /* defined(__clang__) */
481#endif /* defined(__BIONIC_FORTIFY) */