• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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* __memchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
34 void* __memrchr_chk(const void*, int, size_t, size_t) __INTRODUCED_IN(23);
35 char* __stpncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
36 char* __strncpy_chk2(char*, const char*, size_t, size_t, size_t) __INTRODUCED_IN(21);
37 size_t __strlcpy_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
38 size_t __strlcat_chk(char*, const char*, size_t, size_t) __INTRODUCED_IN(17);
39 
40 #if defined(__BIONIC_FORTIFY)
41 extern 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
memcpy(void * const dst __pass_object_size0,const void * src,size_t copy_amount)47 void* 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
memmove(void * const dst __pass_object_size0,const void * src,size_t len)55 void* 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
stpcpy(char * const dst __pass_object_size,const char * src)65 char* 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
strcpy(char * const dst __pass_object_size,const char * src)76 char* 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
strcat(char * const dst __pass_object_size,const char * src)85 char* 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
strncat(char * const dst __pass_object_size,const char * src,size_t n)90 char* 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
memset(void * const s __pass_object_size0,int c,size_t n)95 void* 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
memchr(const void * const s __pass_object_size,int c,size_t n)110 void* 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
__memrchr_fortify(const void * const __pass_object_size s,int c,size_t n)121 void* __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
stpncpy(char * const dst __pass_object_size,const char * const src __pass_object_size,size_t n)134 char* 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
strncpy(char * const dst __pass_object_size,const char * const src __pass_object_size,size_t n)148 char* 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
strlcpy(char * const dst __pass_object_size,const char * src,size_t size)164 size_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
strlcat(char * const dst __pass_object_size,const char * src,size_t size)175 size_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
strlen(const char * const s __pass_object_size)192 size_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
strlen(const char * const s __pass_object_size0)199 size_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
strchr(const char * const s __pass_object_size,int c)212 char* 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
strrchr(const char * const s __pass_object_size,int c)223 char* 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__)
235 extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy);
236 extern size_t __strlcpy_real(char*, const char*, size_t)
237     __RENAME(strlcpy);
238 extern 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
memchr(const void * s __pass_object_size,int c,size_t n)246 void* 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
__memrchr_fortify(const void * s,int c,size_t n)265 void* __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
stpncpy(char * dst,const char * src,size_t n)286 char* 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
strncpy(char * dst,const char * src,size_t n)307 char* 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
strlcpy(char * dst __pass_object_size,const char * src,size_t size)330 size_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
strlcat(char * dst,const char * src,size_t size)348 size_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
strlen(const char * s)366 size_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
strchr(const char * s,int c)385 char* 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
strrchr(const char * s,int c)402 char* 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)
422 extern "C++" {
423 __BIONIC_FORTIFY_INLINE
memrchr(void * const __pass_object_size s,int c,size_t n)424 void* 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
memrchr(const void * const __pass_object_size s,int c,size_t n)429 const 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
memrchr(const void * const __pass_object_size s,int c,size_t n)435 void* 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