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 33void* __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); 39 40#if defined(__BIONIC_FORTIFY) 41extern 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 47void* 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 55void* 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 65char* 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 76char* 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 85char* 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 90char* 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 95void* 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 110void* 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 121void* __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 134char* 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 148char* 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 164size_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 175size_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 192size_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 199size_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 212char* 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 223char* 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__) 235extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy); 236extern size_t __strlcpy_real(char*, const char*, size_t) 237 __RENAME(strlcpy); 238extern 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 246void* 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 265void* __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 286char* 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 307char* 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 330size_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 348size_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 366size_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 385char* 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 402char* 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) 422extern "C++" { 423__BIONIC_FORTIFY_INLINE 424void* 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 429const 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 435void* 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