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
33 void* _Nullable __memchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
34 void* _Nullable __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23);
35 char* _Nonnull __stpncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t);
36 char* _Nonnull __strncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t);
37 size_t __strlcpy_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t);
38 size_t __strlcat_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t);
39
40 #if defined(__BIONIC_FORTIFY)
41 extern void* _Nullable __memrchr_real(const void* _Nonnull, int, size_t) __RENAME(memrchr);
42
43 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
44 /* No diag -- clang diagnoses misuses of this on its own. */
45 __BIONIC_FORTIFY_INLINE
memcpy(void * _Nonnull const dst __pass_object_size0,const void * _Nonnull src,size_t copy_amount)46 void* _Nonnull memcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount)
47 __diagnose_as_builtin(__builtin_memcpy, 1, 2, 3)
48 __overloadable {
49 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
50 }
51
52 /* No diag -- clang diagnoses misuses of this on its own. */
53 __BIONIC_FORTIFY_INLINE
memmove(void * _Nonnull const dst __pass_object_size0,const void * _Nonnull src,size_t len)54 void* _Nonnull memmove(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t len)
55 __diagnose_as_builtin(__builtin_memmove, 1, 2, 3)
56 __overloadable {
57 return __builtin___memmove_chk(dst, src, len, __bos0(dst));
58 }
59 #endif
60
61 #if defined(__USE_GNU)
62 #if __ANDROID_API__ >= 30
63 __BIONIC_FORTIFY_INLINE
mempcpy(void * _Nonnull const dst __pass_object_size0,const void * _Nonnull src,size_t copy_amount)64 void* _Nonnull mempcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount)
65 __diagnose_as_builtin(__builtin_mempcpy, 1, 2, 3)
66 __overloadable
67 __clang_error_if(__bos_unevaluated_lt(__bos0(dst), copy_amount),
68 "'mempcpy' called with size bigger than buffer") {
69 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
70 size_t bos_dst = __bos0(dst);
71 if (!__bos_trivially_ge(bos_dst, copy_amount)) {
72 return __builtin___mempcpy_chk(dst, src, copy_amount, bos_dst);
73 }
74 #endif
75 return __builtin_mempcpy(dst, src, copy_amount);
76 }
77 #endif /* __ANDROID_API__ >= 30 */
78 #endif /* __USE_GNU */
79
80 __BIONIC_FORTIFY_INLINE
stpcpy(char * _Nonnull const dst __pass_object_size,const char * _Nonnull src)81 char* _Nonnull stpcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
82 __overloadable
83 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
84 "'stpcpy' called with string bigger than buffer") {
85 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
86 return __builtin___stpcpy_chk(dst, src, __bos(dst));
87 #else
88 return __builtin_stpcpy(dst, src);
89 #endif
90 }
91
92 __BIONIC_FORTIFY_INLINE
strcpy(char * _Nonnull const dst __pass_object_size,const char * _Nonnull src)93 char* _Nonnull strcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
94 __diagnose_as_builtin(__builtin_strcpy, 1, 2)
95 __overloadable
96 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
97 "'strcpy' called with string bigger than buffer") {
98 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
99 return __builtin___strcpy_chk(dst, src, __bos(dst));
100 #else
101 return __builtin_strcpy(dst, src);
102 #endif
103 }
104
105 __BIONIC_FORTIFY_INLINE
strcat(char * _Nonnull const dst __pass_object_size,const char * _Nonnull src)106 char* _Nonnull strcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src)
107 __overloadable
108 __clang_error_if(__bos_unevaluated_le(__bos(dst), __builtin_strlen(src)),
109 "'strcat' called with string bigger than buffer") {
110 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
111 return __builtin___strcat_chk(dst, src, __bos(dst));
112 #else
113 return __builtin_strcat(dst, src);
114 #endif
115 }
116
117 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
118 /* No diag -- clang diagnoses misuses of this on its own. */
119 __BIONIC_FORTIFY_INLINE
strncat(char * _Nonnull const dst __pass_object_size,const char * _Nonnull src,size_t n)120 char* _Nonnull strncat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t n)
121 __diagnose_as_builtin(__builtin_strncat, 1, 2, 3)
122 __overloadable {
123 return __builtin___strncat_chk(dst, src, n, __bos(dst));
124 }
125 #endif
126
127 /* No diag -- clang diagnoses misuses of this on its own. */
128 __BIONIC_FORTIFY_INLINE
memset(void * _Nonnull const s __pass_object_size0,int c,size_t n)129 void* _Nonnull memset(void* _Nonnull const s __pass_object_size0, int c, size_t n) __overloadable
130 __diagnose_as_builtin(__builtin_memset, 1, 2, 3)
131 /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
132 __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
133 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
134 return __builtin___memset_chk(s, c, n, __bos0(s));
135 #else
136 return __builtin_memset(s, c, n);
137 #endif
138 }
139
140 #if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
141 __BIONIC_FORTIFY_INLINE
memchr(const void * _Nonnull const s __pass_object_size,int c,size_t n)142 void* _Nullable memchr(const void* _Nonnull const s __pass_object_size, int c, size_t n) __overloadable {
143 size_t bos = __bos(s);
144
145 if (__bos_trivially_ge(bos, n)) {
146 return __builtin_memchr(s, c, n);
147 }
148
149 return __memchr_chk(s, c, n, bos);
150 }
151
152 __BIONIC_FORTIFY_INLINE
__memrchr_fortify(const void * _Nonnull const __pass_object_size s,int c,size_t n)153 void* _Nullable __memrchr_fortify(const void* _Nonnull const __pass_object_size s, int c, size_t n) __overloadable {
154 size_t bos = __bos(s);
155
156 if (__bos_trivially_ge(bos, n)) {
157 return __memrchr_real(s, c, n);
158 }
159
160 return __memrchr_chk(s, c, n, bos);
161 }
162 #endif
163
164 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
165 /* No diag -- clang diagnoses misuses of this on its own. */
166 __BIONIC_FORTIFY_INLINE
stpncpy(char * _Nonnull const dst __pass_object_size,const char * _Nonnull const src __pass_object_size,size_t n)167 char* _Nonnull stpncpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull const src __pass_object_size, size_t n)
168 __diagnose_as_builtin(__builtin_stpncpy, 1, 2, 3)
169 __overloadable {
170 size_t bos_dst = __bos(dst);
171 size_t bos_src = __bos(src);
172
173 /* Ignore dst size checks; they're handled in strncpy_chk */
174 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
175 return __builtin___stpncpy_chk(dst, src, n, bos_dst);
176 }
177
178 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
179 }
180
181 /* No diag -- clang diagnoses misuses of this on its own. */
182 __BIONIC_FORTIFY_INLINE
strncpy(char * _Nonnull const dst __pass_object_size,const char * _Nonnull const src __pass_object_size,size_t n)183 char* _Nonnull strncpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull const src __pass_object_size, size_t n)
184 __diagnose_as_builtin(__builtin_strncpy, 1, 2, 3)
185 __overloadable {
186 size_t bos_dst = __bos(dst);
187 size_t bos_src = __bos(src);
188
189 /* Ignore dst size checks; they're handled in strncpy_chk */
190 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
191 return __builtin___strncpy_chk(dst, src, n, bos_dst);
192 }
193
194 return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
195 }
196 #endif
197
198 __BIONIC_FORTIFY_INLINE
strlcpy(char * _Nonnull const dst __pass_object_size,const char * _Nonnull src,size_t size)199 size_t strlcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t size)
200 __overloadable
201 __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
202 "'strlcpy' called with size bigger than buffer") {
203 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
204 return __strlcpy_chk(dst, src, size, __bos(dst));
205 #else
206 return __call_bypassing_fortify(strlcpy)(dst, src, size);
207 #endif
208 }
209
210 __BIONIC_FORTIFY_INLINE
strlcat(char * _Nonnull const dst __pass_object_size,const char * _Nonnull src,size_t size)211 size_t strlcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src, size_t size)
212 __overloadable
213 __clang_error_if(__bos_unevaluated_lt(__bos(dst), size),
214 "'strlcat' called with size bigger than buffer") {
215 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
216 return __strlcat_chk(dst, src, size, __bos(dst));
217 #else
218 return __call_bypassing_fortify(strlcat)(dst, src, size);
219 #endif
220 }
221
222 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
223 __BIONIC_FORTIFY_INLINE
strlen(const char * _Nonnull const s __pass_object_size0)224 size_t strlen(const char* _Nonnull const s __pass_object_size0) __overloadable {
225 return __strlen_chk(s, __bos0(s));
226 }
227 #endif
228
229 __BIONIC_FORTIFY_INLINE
strchr(const char * _Nonnull const s __pass_object_size,int c)230 char* _Nullable strchr(const char* _Nonnull const s __pass_object_size, int c) __overloadable {
231 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
232 size_t bos = __bos(s);
233
234 if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
235 return __strchr_chk(s, c, bos);
236 }
237 #endif
238 return __builtin_strchr(s, c);
239 }
240
241 __BIONIC_FORTIFY_INLINE
strrchr(const char * _Nonnull const s __pass_object_size,int c)242 char* _Nullable strrchr(const char* _Nonnull const s __pass_object_size, int c) __overloadable {
243 #if __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
244 size_t bos = __bos(s);
245
246 if (bos != __BIONIC_FORTIFY_UNKNOWN_SIZE) {
247 return __strrchr_chk(s, c, bos);
248 }
249 #endif
250 return __builtin_strrchr(s, c);
251 }
252
253 #if __ANDROID_API__ >= 23 && __BIONIC_FORTIFY_RUNTIME_CHECKS_ENABLED
254 #if defined(__cplusplus)
255 extern "C++" {
256 __BIONIC_FORTIFY_INLINE
memrchr(void * _Nonnull const __pass_object_size s,int c,size_t n)257 void* _Nullable memrchr(void* _Nonnull const __pass_object_size s, int c, size_t n) {
258 return __memrchr_fortify(s, c, n);
259 }
260
261 __BIONIC_FORTIFY_INLINE
memrchr(const void * _Nonnull const __pass_object_size s,int c,size_t n)262 const void* _Nullable memrchr(const void* _Nonnull const __pass_object_size s, int c, size_t n) {
263 return __memrchr_fortify(s, c, n);
264 }
265 }
266 #else
267 __BIONIC_FORTIFY_INLINE
memrchr(const void * _Nonnull const __pass_object_size s,int c,size_t n)268 void* _Nullable memrchr(const void* _Nonnull const __pass_object_size s, int c, size_t n) __overloadable {
269 return __memrchr_fortify(s, c, n);
270 }
271 #endif
272 #endif /* __ANDROID_API__ >= 23 */
273
274 #endif /* defined(__BIONIC_FORTIFY) */
275