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