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
33void* __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);
39
40#if defined(__BIONIC_FORTIFY)
41extern 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
47void* 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
55void* 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
65char* 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
76char* 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
85char* 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
90char* 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
95void* 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
110void* 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
121void* __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
134char* 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
148char* 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
164size_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
175size_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
192size_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
199size_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
212char* 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
223char* 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__)
235extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
236extern size_t __strlcpy_real(char*, const char*, size_t)
237    __RENAME(strlcpy);
238extern 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
246void* 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
265void* __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
286char* 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
307char* 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
330size_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
348size_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
366size_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
385char* 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
402char* 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)
422extern "C++" {
423__BIONIC_FORTIFY_INLINE
424void* 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
429const 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
435void* 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