blob: 667e21d1a07d36c80ccd40bc3df5840267f5adb7 [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
Elliott Hughes3f66e742017-08-01 13:24:40 -070033void* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
34void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
35char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
36char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
37size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
38size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
George Burgess IVb97049c2017-07-24 15:05:05 -070039
George Burgess IVb97049c2017-07-24 15:05:05 -070040#if defined(__BIONIC_FORTIFY)
41// These can share their implementation between gcc and clang with minimal
42// trickery...
43#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
44__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070045void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
46 __overloadable
47 __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount,
48 "'memcpy' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -070049 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
50}
51
52__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070053void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
54 __overloadable
55 __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len,
56 "'memmove' called with size bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -070057 return __builtin___memmove_chk(dst, src, len, __bos0(dst));
58}
59#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
60
61#if __ANDROID_API__ >= __ANDROID_API_L__
62__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070063char* stpcpy(char* const dst __pass_object_size, const char* src)
64 __overloadable
65 __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
66 __bos(dst) <= __builtin_strlen(src),
67 "'stpcpy' called with string bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -070068 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
George Burgess IVb6300462017-07-31 21:29:42 -070074char* strcpy(char* const dst __pass_object_size, const char* src)
75 __overloadable
76 __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
77 __bos(dst) <= __builtin_strlen(src),
78 "'strcpy' called with string bigger than buffer") {
George Burgess IVb97049c2017-07-24 15:05:05 -070079 return __builtin___strcpy_chk(dst, src, __bos(dst));
80}
81
82__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070083char* strcat(char* const dst __pass_object_size, const char* src) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070084 return __builtin___strcat_chk(dst, src, __bos(dst));
85}
86
87__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -070088char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -070089 return __builtin___strncat_chk(dst, src, n, __bos(dst));
90}
91
92__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070093void* memset(void* const s __pass_object_size0, int c, size_t n)
94 __overloadable
95 __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n,
96 "'memset' called with size bigger than buffer")
97 /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
98 __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
George Burgess IVb97049c2017-07-24 15:05:05 -070099 return __builtin___memset_chk(s, c, n, __bos0(s));
100}
101#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
102
103
104#if defined(__clang__)
105
George Burgess IVb97049c2017-07-24 15:05:05 -0700106#if __ANDROID_API__ >= __ANDROID_API_M__
107__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700108void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700109 size_t bos = __bos(s);
110
111 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
112 return __builtin_memchr(s, c, n);
113 }
114
115 return __memchr_chk(s, c, n, bos);
116}
117
118__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700119void* memrchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700120 size_t bos = __bos(s);
121
122 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
123 return __call_bypassing_fortify(memrchr)(s, c, n);
124 }
125
126 return __memrchr_chk(s, c, n, bos);
127}
128#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
129
130#if __ANDROID_API__ >= __ANDROID_API_L__
131__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700132char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IVb97049c2017-07-24 15:05:05 -0700133 __overloadable {
134 size_t bos_dst = __bos(dst);
135 size_t bos_src = __bos(src);
136
137 /* Ignore dst size checks; they're handled in strncpy_chk */
138 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
139 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
140 }
141
142 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
143}
144
145__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700146char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IVb97049c2017-07-24 15:05:05 -0700147 __overloadable {
148 size_t bos_dst = __bos(dst);
149 size_t bos_src = __bos(src);
150
151 /* Ignore dst size checks; they're handled in strncpy_chk */
152 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
153 return __builtin___strncpy_chk(dst, src, n, bos_dst);
154 }
155
156 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
157}
158#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
159
160#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
161__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700162size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700163 size_t bos = __bos(dst);
164
165 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
166 return __call_bypassing_fortify(strlcpy)(dst, src, size);
167 }
168
169 return __strlcpy_chk(dst, src, size, bos);
170}
171
172__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700173size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700174 size_t bos = __bos(dst);
175
176 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
177 return __call_bypassing_fortify(strlcat)(dst, src, size);
178 }
179
180 return __strlcat_chk(dst, src, size, bos);
181}
182
183/*
184 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
185 * on it directly. This makes it way easier for compilers to fold things like
186 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
187 * because it's large.
188 */
189__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700190size_t strlen(const char* const s __pass_object_size)
George Burgess IVb97049c2017-07-24 15:05:05 -0700191 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
192 "enabled if s is a known good string.") {
193 return __builtin_strlen(s);
194}
195
196__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700197size_t strlen(const char* const s __pass_object_size0) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700198 size_t bos = __bos0(s);
199
200 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
201 return __builtin_strlen(s);
202 }
203
George Burgess IVb97049c2017-07-24 15:05:05 -0700204 return __strlen_chk(s, bos);
205}
206#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
207
208#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
209__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700210char* strchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700211 size_t bos = __bos(s);
212
213 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
214 return __builtin_strchr(s, c);
215 }
216
217 return __strchr_chk(s, c, bos);
218}
219
220__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700221char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700222 size_t bos = __bos(s);
223
224 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
225 return __builtin_strrchr(s, c);
226 }
227
228 return __strrchr_chk(s, c, bos);
229}
230#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
231
George Burgess IVb97049c2017-07-24 15:05:05 -0700232#else // defined(__clang__)
Elliott Hughesec6850d2017-08-01 08:28:46 -0700233extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
George Burgess IVb97049c2017-07-24 15:05:05 -0700234extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
Elliott Hughesec6850d2017-08-01 08:28:46 -0700235extern size_t __strlcpy_real(char*, const char*, size_t)
George Burgess IVb97049c2017-07-24 15:05:05 -0700236 __RENAME(strlcpy);
Elliott Hughesec6850d2017-08-01 08:28:46 -0700237extern size_t __strlcat_real(char*, const char*, size_t)
George Burgess IVb97049c2017-07-24 15:05:05 -0700238 __RENAME(strlcat);
239
240__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer");
241__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer");
242
243#if __ANDROID_API__ >= __ANDROID_API_M__
244__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700245void* memchr(const void* s __pass_object_size, int c, size_t n) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700246 size_t bos = __bos(s);
247
248 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
249 return __builtin_memchr(s, c, n);
250 }
251
252 if (__builtin_constant_p(n) && (n > bos)) {
253 __memchr_buf_size_error();
254 }
255
256 if (__builtin_constant_p(n) && (n <= bos)) {
257 return __builtin_memchr(s, c, n);
258 }
259
260 return __memchr_chk(s, c, n, bos);
261}
262
263__BIONIC_FORTIFY_INLINE
264void* memrchr(const void* s, int c, size_t n) {
265 size_t bos = __bos(s);
266
267 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
268 return __memrchr_real(s, c, n);
269 }
270
271 if (__builtin_constant_p(n) && (n > bos)) {
272 __memrchr_buf_size_error();
273 }
274
275 if (__builtin_constant_p(n) && (n <= bos)) {
276 return __memrchr_real(s, c, n);
277 }
278
279 return __memrchr_chk(s, c, n, bos);
280}
281#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
282
283#if __ANDROID_API__ >= __ANDROID_API_L__
284__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700285char* stpncpy(char* dst, const char* src, size_t n) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700286 size_t bos_dst = __bos(dst);
287 size_t bos_src = __bos(src);
288
289 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
290 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
291 }
292
293 if (__builtin_constant_p(n) && (n <= bos_src)) {
294 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
295 }
296
297 size_t slen = __builtin_strlen(src);
298 if (__builtin_constant_p(slen)) {
299 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
300 }
301
302 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
303}
304
305__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700306char* strncpy(char* dst, const char* src, size_t n) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700307 size_t bos_dst = __bos(dst);
308 size_t bos_src = __bos(src);
309
310 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
311 return __strncpy_real(dst, src, n);
312 }
313
314 if (__builtin_constant_p(n) && (n <= bos_src)) {
315 return __builtin___strncpy_chk(dst, src, n, bos_dst);
316 }
317
318 size_t slen = __builtin_strlen(src);
319 if (__builtin_constant_p(slen)) {
320 return __builtin___strncpy_chk(dst, src, n, bos_dst);
321 }
322
323 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
324}
325#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
326
327#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
328__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700329size_t strlcpy(char* dst __pass_object_size, const char* src, size_t size) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700330 size_t bos = __bos(dst);
331
332 // Compiler doesn't know destination size. Don't call __strlcpy_chk
333 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
334 return __strlcpy_real(dst, src, size);
335 }
336
337 // Compiler can prove, at compile time, that the passed in size
338 // is always <= the actual object size. Don't call __strlcpy_chk
339 if (__builtin_constant_p(size) && (size <= bos)) {
340 return __strlcpy_real(dst, src, size);
341 }
342
343 return __strlcpy_chk(dst, src, size, bos);
344}
345
346__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700347size_t strlcat(char* dst, const char* src, size_t size) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700348 size_t bos = __bos(dst);
349
350 // Compiler doesn't know destination size. Don't call __strlcat_chk
351 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
352 return __strlcat_real(dst, src, size);
353 }
354
355 // Compiler can prove, at compile time, that the passed in size
356 // is always <= the actual object size. Don't call __strlcat_chk
357 if (__builtin_constant_p(size) && (size <= bos)) {
358 return __strlcat_real(dst, src, size);
359 }
360
361 return __strlcat_chk(dst, src, size, bos);
362}
363
364__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700365size_t strlen(const char* s) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700366 size_t bos = __bos(s);
367
368 // Compiler doesn't know destination size. Don't call __strlen_chk
369 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
370 return __builtin_strlen(s);
371 }
372
373 size_t slen = __builtin_strlen(s);
374 if (__builtin_constant_p(slen)) {
375 return slen;
376 }
377
378 return __strlen_chk(s, bos);
379}
380#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
381
382#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
383__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700384char* strchr(const char* s, int c) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700385 size_t bos = __bos(s);
386
387 // Compiler doesn't know destination size. Don't call __strchr_chk
388 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
389 return __builtin_strchr(s, c);
390 }
391
392 size_t slen = __builtin_strlen(s);
393 if (__builtin_constant_p(slen) && (slen < bos)) {
394 return __builtin_strchr(s, c);
395 }
396
397 return __strchr_chk(s, c, bos);
398}
399
400__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700401char* strrchr(const char* s, int c) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700402 size_t bos = __bos(s);
403
404 // Compiler doesn't know destination size. Don't call __strrchr_chk
405 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
406 return __builtin_strrchr(s, c);
407 }
408
409 size_t slen = __builtin_strlen(s);
410 if (__builtin_constant_p(slen) && (slen < bos)) {
411 return __builtin_strrchr(s, c);
412 }
413
414 return __strrchr_chk(s, c, bos);
415}
416#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
417#endif /* defined(__clang__) */
418#endif /* defined(__BIONIC_FORTIFY) */