blob: 7dc60f2c24ae27a0b1100a3133b9e93e3052bedc [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)
Elliott Hughesdf9a4892017-08-23 14:34:03 -070041extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr);
42
George Burgess IV8a0cdb12019-10-21 13:27:57 -070043#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV36926f42019-09-15 16:57:00 -070044/* No diag -- clang diagnoses misuses of this on its own. */
George Burgess IVb97049c2017-07-24 15:05:05 -070045__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070046void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
George Burgess IV36926f42019-09-15 16:57:00 -070047 __overloadable {
George Burgess IV5da5dd52019-05-09 14:32:43 -070048 size_t bos_dst = __bos0(dst);
George Burgess IV3aedee92019-09-24 11:46:22 -070049 if (__bos_trivially_ge(bos_dst, copy_amount)) {
George Burgess IV5da5dd52019-05-09 14:32:43 -070050 return __builtin_memcpy(dst, src, copy_amount);
51 }
52 return __builtin___memcpy_chk(dst, src, copy_amount, bos_dst);
George Burgess IVb97049c2017-07-24 15:05:05 -070053}
54
George Burgess IV36926f42019-09-15 16:57:00 -070055/* No diag -- clang diagnoses misuses of this on its own. */
George Burgess IVb97049c2017-07-24 15:05:05 -070056__BIONIC_FORTIFY_INLINE
George Burgess IV36926f42019-09-15 16:57:00 -070057void* memmove(void* const dst __pass_object_size0, const void* src, size_t len) __overloadable {
George Burgess IV5da5dd52019-05-09 14:32:43 -070058 size_t bos_dst = __bos0(dst);
George Burgess IV3aedee92019-09-24 11:46:22 -070059 if (__bos_trivially_ge(bos_dst, len)) {
George Burgess IV5da5dd52019-05-09 14:32:43 -070060 return __builtin_memmove(dst, src, len);
61 }
62 return __builtin___memmove_chk(dst, src, len, bos_dst);
George Burgess IVb97049c2017-07-24 15:05:05 -070063}
George Burgess IV8a0cdb12019-10-21 13:27:57 -070064#endif
George Burgess IVb97049c2017-07-24 15:05:05 -070065
George Burgess IV849c0b92019-06-10 16:22:09 -070066#if defined(__USE_GNU)
67#if __ANDROID_API__ >= __ANDROID_API_R__
68__BIONIC_FORTIFY_INLINE
69void* mempcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
70 __overloadable
71 __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
72 "'mempcpy' called with size bigger than buffer") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -070073#if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV849c0b92019-06-10 16:22:09 -070074 size_t bos_dst = __bos0(dst);
George Burgess IV8a0cdb12019-10-21 13:27:57 -070075 if (!__bos_trivially_ge(bos_dst, copy_amount)) {
76 return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);
George Burgess IV849c0b92019-06-10 16:22:09 -070077 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -070078#endif
79 return __builtin_mempcpy(dst, src, copy_amount);
George Burgess IV849c0b92019-06-10 16:22:09 -070080}
81#endif /* __ANDROID_API__ >= __ANDROID_API_R__ */
George Burgess IVfd1ff4b2019-09-18 17:29:55 -070082#endif /* __USE_GNU */
George Burgess IV849c0b92019-06-10 16:22:09 -070083
George Burgess IVb97049c2017-07-24 15:05:05 -070084__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070085char* stpcpy(char* const dst __pass_object_size, const char* src)
86 __overloadable
George Burgess IVc03d5962019-05-23 15:22:01 -070087 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
George Burgess IVb6300462017-07-31 21:29:42 -070088 "'stpcpy' called with string bigger than buffer") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -070089#if __ANDROID_API__ >= __ANDROID_API_L__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV5da5dd52019-05-09 14:32:43 -070090 size_t bos_dst = __bos(dst);
George Burgess IVfd1ff4b2019-09-18 17:29:55 -070091 if (!__bos_trivially_gt(bos_dst, __builtin_strlen(src))) {
92 return __builtin___stpcpy_chk(dst, src, bos_dst);
George Burgess IV5da5dd52019-05-09 14:32:43 -070093 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -070094#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -070095 return __builtin_stpcpy(dst, src);
96}
George Burgess IVb97049c2017-07-24 15:05:05 -070097
George Burgess IVb97049c2017-07-24 15:05:05 -070098__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -070099char* strcpy(char* const dst __pass_object_size, const char* src)
100 __overloadable
George Burgess IVc03d5962019-05-23 15:22:01 -0700101 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
George Burgess IVb6300462017-07-31 21:29:42 -0700102 "'strcpy' called with string bigger than buffer") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700103#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV5da5dd52019-05-09 14:32:43 -0700104 size_t bos_dst = __bos(dst);
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700105 if (!__bos_trivially_gt(bos_dst, __builtin_strlen(src))) {
106 return __builtin___strcpy_chk(dst, src, bos_dst);
George Burgess IV5da5dd52019-05-09 14:32:43 -0700107 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700108#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700109 return __builtin_strcpy(dst, src);
George Burgess IVb97049c2017-07-24 15:05:05 -0700110}
111
112__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -0700113char* strcat(char* const dst __pass_object_size, const char* src)
114 __overloadable
115 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
116 "'strcat' called with string bigger than buffer") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700117#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700118 return __builtin___strcat_chk(dst, src, __bos(dst));
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700119#else
120 return __builtin_strcat(dst, src);
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700121#endif
George Burgess IVb97049c2017-07-24 15:05:05 -0700122}
123
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700124#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV36926f42019-09-15 16:57:00 -0700125/* No diag -- clang diagnoses misuses of this on its own. */
George Burgess IVb97049c2017-07-24 15:05:05 -0700126__BIONIC_FORTIFY_INLINE
George Burgess IV36926f42019-09-15 16:57:00 -0700127char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700128 return __builtin___strncat_chk(dst, src, n, __bos(dst));
129}
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700130#endif
George Burgess IVb97049c2017-07-24 15:05:05 -0700131
George Burgess IV36926f42019-09-15 16:57:00 -0700132/* No diag -- clang diagnoses misuses of this on its own. */
George Burgess IVb97049c2017-07-24 15:05:05 -0700133__BIONIC_FORTIFY_INLINE
George Burgess IV36926f42019-09-15 16:57:00 -0700134void* memset(void* const s __pass_object_size0, int c, size_t n) __overloadable
George Burgess IVb6300462017-07-31 21:29:42 -0700135 /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
136 __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700137#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV5da5dd52019-05-09 14:32:43 -0700138 size_t bos = __bos0(s);
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700139 if (!__bos_trivially_ge(bos, n)) {
140 return __builtin___memset_chk(s, c, n, bos);
George Burgess IV5da5dd52019-05-09 14:32:43 -0700141 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700142#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700143 return __builtin_memset(s, c, n);
144}
George Burgess IVb97049c2017-07-24 15:05:05 -0700145
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700146#if __ANDROID_API__ >= __ANDROID_API_M__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700147__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700148void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700149 size_t bos = __bos(s);
150
George Burgess IVc03d5962019-05-23 15:22:01 -0700151 if (__bos_trivially_ge(bos, n)) {
George Burgess IVb97049c2017-07-24 15:05:05 -0700152 return __builtin_memchr(s, c, n);
153 }
154
155 return __memchr_chk(s, c, n, bos);
156}
157
158__BIONIC_FORTIFY_INLINE
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700159void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700160 size_t bos = __bos(s);
161
George Burgess IVc03d5962019-05-23 15:22:01 -0700162 if (__bos_trivially_ge(bos, n)) {
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700163 return __memrchr_real(s, c, n);
George Burgess IVb97049c2017-07-24 15:05:05 -0700164 }
165
166 return __memrchr_chk(s, c, n, bos);
167}
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700168#endif
George Burgess IVb97049c2017-07-24 15:05:05 -0700169
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700170#if __ANDROID_API__ >= __ANDROID_API_L__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IV36926f42019-09-15 16:57:00 -0700171/* No diag -- clang diagnoses misuses of this on its own. */
George Burgess IVb97049c2017-07-24 15:05:05 -0700172__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700173char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IV36926f42019-09-15 16:57:00 -0700174 __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700175 size_t bos_dst = __bos(dst);
176 size_t bos_src = __bos(src);
177
178 /* Ignore dst size checks; they're handled in strncpy_chk */
179 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
180 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
181 }
182
183 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
184}
185
George Burgess IV36926f42019-09-15 16:57:00 -0700186/* No diag -- clang diagnoses misuses of this on its own. */
George Burgess IVb97049c2017-07-24 15:05:05 -0700187__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700188char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
George Burgess IV36926f42019-09-15 16:57:00 -0700189 __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700190 size_t bos_dst = __bos(dst);
191 size_t bos_src = __bos(src);
192
193 /* Ignore dst size checks; they're handled in strncpy_chk */
194 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
195 return __builtin___strncpy_chk(dst, src, n, bos_dst);
196 }
197
198 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
199}
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700200#endif
George Burgess IVb97049c2017-07-24 15:05:05 -0700201
George Burgess IVb97049c2017-07-24 15:05:05 -0700202__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -0700203size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size)
204 __overloadable
205 __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
206 "'strlcpy' called with size bigger than buffer") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700207#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700208 size_t bos = __bos(dst);
209
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700210 if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
211 return __strlcpy_chk(dst, src, size, bos);
George Burgess IVb97049c2017-07-24 15:05:05 -0700212 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700213#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700214 return __call_bypassing_fortify(strlcpy)(dst, src, size);
George Burgess IVb97049c2017-07-24 15:05:05 -0700215}
216
217__BIONIC_FORTIFY_INLINE
George Burgess IV77f99aa2019-06-06 14:14:52 -0700218size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size)
219 __overloadable
220 __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
221 "'strlcat' called with size bigger than buffer") {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700222#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700223 size_t bos = __bos(dst);
224
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700225 if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
226 return __strlcat_chk(dst, src, size, bos);
George Burgess IVb97049c2017-07-24 15:05:05 -0700227 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700228#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700229 return __call_bypassing_fortify(strlcat)(dst, src, size);
George Burgess IVb97049c2017-07-24 15:05:05 -0700230}
231
George Burgess IVb97049c2017-07-24 15:05:05 -0700232__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700233size_t strlen(const char* const s __pass_object_size0) __overloadable {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700234#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700235 size_t bos = __bos0(s);
236
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700237 if (!__bos_trivially_gt(bos, __builtin_strlen(s))) {
238 return __strlen_chk(s, bos);
George Burgess IVb97049c2017-07-24 15:05:05 -0700239 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700240#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700241 return __builtin_strlen(s);
242}
George Burgess IVb97049c2017-07-24 15:05:05 -0700243
George Burgess IVb97049c2017-07-24 15:05:05 -0700244__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700245char* strchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700246#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700247 size_t bos = __bos(s);
248
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700249 if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
250 return __strchr_chk(s, c, bos);
George Burgess IVb97049c2017-07-24 15:05:05 -0700251 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700252#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700253 return __builtin_strchr(s, c);
George Burgess IVb97049c2017-07-24 15:05:05 -0700254}
255
256__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700257char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700258#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
George Burgess IVb97049c2017-07-24 15:05:05 -0700259 size_t bos = __bos(s);
260
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700261 if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
262 return __strrchr_chk(s, c, bos);
George Burgess IVb97049c2017-07-24 15:05:05 -0700263 }
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700264#endif
George Burgess IVfd1ff4b2019-09-18 17:29:55 -0700265 return __builtin_strrchr(s, c);
266}
George Burgess IVb97049c2017-07-24 15:05:05 -0700267
George Burgess IV8a0cdb12019-10-21 13:27:57 -0700268#if __ANDROID_API__ >= __ANDROID_API_M__ && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700269#if defined(__cplusplus)
270extern "C++" {
271__BIONIC_FORTIFY_INLINE
272void* memrchr(void* const __pass_object_size s, int c, size_t n) {
273 return __memrchr_fortify(s, c, n);
274}
275
276__BIONIC_FORTIFY_INLINE
277const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
278 return __memrchr_fortify(s, c, n);
279}
280}
281#else
282__BIONIC_FORTIFY_INLINE
283void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
284 return __memrchr_fortify(s, c, n);
285}
286#endif
287#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
288
George Burgess IVb97049c2017-07-24 15:05:05 -0700289#endif /* defined(__BIONIC_FORTIFY) */