blob: 14bb1335b7c9b25554f2fc827a883d22e6752b0c [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 IVb97049c2017-07-24 15:05:05 -070043#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
George Burgess IVb97049c2017-07-24 15:05:05 -0700103#if __ANDROID_API__ >= __ANDROID_API_M__
104__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700105void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700106 size_t bos = __bos(s);
107
108 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
109 return __builtin_memchr(s, c, n);
110 }
111
112 return __memchr_chk(s, c, n, bos);
113}
114
115__BIONIC_FORTIFY_INLINE
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700116void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700117 size_t bos = __bos(s);
118
119 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700120 return __memrchr_real(s, c, n);
George Burgess IVb97049c2017-07-24 15:05:05 -0700121 }
122
123 return __memrchr_chk(s, c, n, bos);
124}
125#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
126
127#if __ANDROID_API__ >= __ANDROID_API_L__
128__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700129char* 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 -0700130 __overloadable {
131 size_t bos_dst = __bos(dst);
132 size_t bos_src = __bos(src);
133
134 /* Ignore dst size checks; they're handled in strncpy_chk */
135 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
136 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
137 }
138
139 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
140}
141
142__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700143char* 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 -0700144 __overloadable {
145 size_t bos_dst = __bos(dst);
146 size_t bos_src = __bos(src);
147
148 /* Ignore dst size checks; they're handled in strncpy_chk */
149 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
150 return __builtin___strncpy_chk(dst, src, n, bos_dst);
151 }
152
153 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
154}
155#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
156
157#if __ANDROID_API__ >= __ANDROID_API_J_MR1__
158__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700159size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700160 size_t bos = __bos(dst);
161
162 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
163 return __call_bypassing_fortify(strlcpy)(dst, src, size);
164 }
165
166 return __strlcpy_chk(dst, src, size, bos);
167}
168
169__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700170size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700171 size_t bos = __bos(dst);
172
173 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
174 return __call_bypassing_fortify(strlcat)(dst, src, size);
175 }
176
177 return __strlcat_chk(dst, src, size, bos);
178}
179
180/*
181 * If we can evaluate the size of s at compile-time, just call __builtin_strlen
182 * on it directly. This makes it way easier for compilers to fold things like
183 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
184 * because it's large.
185 */
186__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700187size_t strlen(const char* const s __pass_object_size)
George Burgess IVb97049c2017-07-24 15:05:05 -0700188 __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
189 "enabled if s is a known good string.") {
190 return __builtin_strlen(s);
191}
192
193__BIONIC_FORTIFY_INLINE
George Burgess IVb6300462017-07-31 21:29:42 -0700194size_t strlen(const char* const s __pass_object_size0) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700195 size_t bos = __bos0(s);
196
197 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
198 return __builtin_strlen(s);
199 }
200
George Burgess IVb97049c2017-07-24 15:05:05 -0700201 return __strlen_chk(s, bos);
202}
203#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
204
205#if __ANDROID_API__ >= __ANDROID_API_J_MR2__
206__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700207char* strchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700208 size_t bos = __bos(s);
209
210 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
211 return __builtin_strchr(s, c);
212 }
213
214 return __strchr_chk(s, c, bos);
215}
216
217__BIONIC_FORTIFY_INLINE
Elliott Hughes3f66e742017-08-01 13:24:40 -0700218char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
George Burgess IVb97049c2017-07-24 15:05:05 -0700219 size_t bos = __bos(s);
220
221 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
222 return __builtin_strrchr(s, c);
223 }
224
225 return __strrchr_chk(s, c, bos);
226}
227#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
228
Elliott Hughesdf9a4892017-08-23 14:34:03 -0700229#if __ANDROID_API__ >= __ANDROID_API_M__
230#if defined(__cplusplus)
231extern "C++" {
232__BIONIC_FORTIFY_INLINE
233void* memrchr(void* const __pass_object_size s, int c, size_t n) {
234 return __memrchr_fortify(s, c, n);
235}
236
237__BIONIC_FORTIFY_INLINE
238const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
239 return __memrchr_fortify(s, c, n);
240}
241}
242#else
243__BIONIC_FORTIFY_INLINE
244void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
245 return __memrchr_fortify(s, c, n);
246}
247#endif
248#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
249
George Burgess IVb97049c2017-07-24 15:05:05 -0700250#endif /* defined(__BIONIC_FORTIFY) */