string.h revision ec6850d849746ffbafaaf9b993c5dbb74a014b3f
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* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23); 34void* __memrchr_chk(const void* _Nonnull, int, size_t, size_t) __INTRODUCED_IN(23); 35char* __stpncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t) 36 __INTRODUCED_IN(21); 37char* __strncpy_chk2(char* _Nonnull, const char* _Nonnull, size_t, size_t, size_t) 38 __INTRODUCED_IN(21); 39size_t __strlcpy_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t) __INTRODUCED_IN(17); 40size_t __strlcat_chk(char* _Nonnull, const char* _Nonnull, size_t, size_t) __INTRODUCED_IN(17); 41 42/* Only used with FORTIFY, but some headers that need it undef FORTIFY, so we 43 * have the definition out here. 44 */ 45struct __bionic_zero_size_is_okay_t {}; 46 47#if defined(__BIONIC_FORTIFY) 48// These can share their implementation between gcc and clang with minimal 49// trickery... 50#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 51__BIONIC_FORTIFY_INLINE 52void* memcpy(void* _Nonnull const dst __pass_object_size0, const void* _Nonnull src, size_t copy_amount) 53 __overloadable { 54 return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst)); 55} 56 57__BIONIC_FORTIFY_INLINE 58void* memmove(void* const _Nonnull dst __pass_object_size0, const void* _Nonnull src, size_t len) 59 __overloadable { 60 return __builtin___memmove_chk(dst, src, len, __bos0(dst)); 61} 62#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 63 64#if __ANDROID_API__ >= __ANDROID_API_L__ 65__BIONIC_FORTIFY_INLINE 66char* stpcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src) 67 __overloadable { 68 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 74char* strcpy(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src) 75 __overloadable { 76 return __builtin___strcpy_chk(dst, src, __bos(dst)); 77} 78 79__BIONIC_FORTIFY_INLINE 80char* strcat(char* _Nonnull const dst __pass_object_size, const char* _Nonnull src) 81 __overloadable { 82 return __builtin___strcat_chk(dst, src, __bos(dst)); 83} 84 85__BIONIC_FORTIFY_INLINE 86char* strncat(char* const _Nonnull dst __pass_object_size, const char* _Nonnull src, size_t n) 87 __overloadable { 88 return __builtin___strncat_chk(dst, src, n, __bos(dst)); 89} 90 91__BIONIC_FORTIFY_INLINE 92void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n) __overloadable { 93 return __builtin___memset_chk(s, c, n, __bos0(s)); 94} 95#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 96 97 98#if defined(__clang__) 99 100#define __error_if_overflows_dst(name, dst, n, what) \ 101 __enable_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && \ 102 __bos0(dst) < (n), "selected when the buffer is too small") \ 103 __errorattr(#name " called with " what " bigger than buffer") 104 105/* 106 * N.B. _Nonnull isn't necessary on params, since these functions just emit 107 * errors. 108 */ 109__BIONIC_ERROR_FUNCTION_VISIBILITY 110void* memcpy(void* dst, const void* src, size_t copy_amount) __overloadable 111 __error_if_overflows_dst(memcpy, dst, copy_amount, "size"); 112 113__BIONIC_ERROR_FUNCTION_VISIBILITY 114void* memmove(void *dst, const void* src, size_t len) __overloadable 115 __error_if_overflows_dst(memmove, dst, len, "size"); 116 117__BIONIC_ERROR_FUNCTION_VISIBILITY 118void* memset(void* s, int c, size_t n) __overloadable 119 __error_if_overflows_dst(memset, s, n, "size"); 120 121__BIONIC_ERROR_FUNCTION_VISIBILITY 122char* stpcpy(char* dst, const char* src) __overloadable 123 __error_if_overflows_dst(stpcpy, dst, __builtin_strlen(src), "string"); 124 125__BIONIC_ERROR_FUNCTION_VISIBILITY 126char* strcpy(char* dst, const char* src) __overloadable 127 __error_if_overflows_dst(strcpy, dst, __builtin_strlen(src), "string"); 128 129#if __ANDROID_API__ >= __ANDROID_API_M__ 130__BIONIC_FORTIFY_INLINE 131void* memchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) 132 __overloadable { 133 size_t bos = __bos(s); 134 135 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 136 return __builtin_memchr(s, c, n); 137 } 138 139 return __memchr_chk(s, c, n, bos); 140} 141 142__BIONIC_FORTIFY_INLINE 143void* memrchr(const void* const _Nonnull s __pass_object_size, int c, size_t n) 144 __overloadable { 145 size_t bos = __bos(s); 146 147 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 148 return __call_bypassing_fortify(memrchr)(s, c, n); 149 } 150 151 return __memrchr_chk(s, c, n, bos); 152} 153#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ 154 155#if __ANDROID_API__ >= __ANDROID_API_L__ 156__BIONIC_FORTIFY_INLINE 157char* stpncpy(char* const _Nonnull dst __pass_object_size, const char* const _Nonnull src __pass_object_size, size_t n) 158 __overloadable { 159 size_t bos_dst = __bos(dst); 160 size_t bos_src = __bos(src); 161 162 /* Ignore dst size checks; they're handled in strncpy_chk */ 163 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 164 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 165 } 166 167 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src); 168} 169 170__BIONIC_FORTIFY_INLINE 171char* strncpy(char* const _Nonnull dst __pass_object_size, const char* const _Nonnull src __pass_object_size, size_t n) 172 __overloadable { 173 size_t bos_dst = __bos(dst); 174 size_t bos_src = __bos(src); 175 176 /* Ignore dst size checks; they're handled in strncpy_chk */ 177 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 178 return __builtin___strncpy_chk(dst, src, n, bos_dst); 179 } 180 181 return __strncpy_chk2(dst, src, n, bos_dst, bos_src); 182} 183#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ 184 185#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 186__BIONIC_FORTIFY_INLINE 187size_t strlcpy(char* const _Nonnull dst __pass_object_size, const char *_Nonnull src, size_t size) 188 __overloadable { 189 size_t bos = __bos(dst); 190 191 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 192 return __call_bypassing_fortify(strlcpy)(dst, src, size); 193 } 194 195 return __strlcpy_chk(dst, src, size, bos); 196} 197 198__BIONIC_FORTIFY_INLINE 199size_t strlcat(char* const _Nonnull dst __pass_object_size, const char* _Nonnull src, size_t size) 200 __overloadable { 201 size_t bos = __bos(dst); 202 203 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 204 return __call_bypassing_fortify(strlcat)(dst, src, size); 205 } 206 207 return __strlcat_chk(dst, src, size, bos); 208} 209 210/* 211 * If we can evaluate the size of s at compile-time, just call __builtin_strlen 212 * on it directly. This makes it way easier for compilers to fold things like 213 * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply 214 * because it's large. 215 */ 216__BIONIC_FORTIFY_INLINE 217size_t strlen(const char* const _Nonnull s __pass_object_size) 218 __overloadable __enable_if(__builtin_strlen(s) != -1ULL, 219 "enabled if s is a known good string.") { 220 return __builtin_strlen(s); 221} 222 223__BIONIC_FORTIFY_INLINE 224size_t strlen(const char* const _Nonnull s __pass_object_size0) 225 __overloadable { 226 size_t bos = __bos0(s); 227 228 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 229 return __builtin_strlen(s); 230 } 231 232 // return __builtin_strlen(s); 233 return __strlen_chk(s, bos); 234} 235#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 236 237#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ 238__BIONIC_FORTIFY_INLINE 239char* strchr(const char* const _Nonnull s __pass_object_size, int c) 240 __overloadable { 241 size_t bos = __bos(s); 242 243 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 244 return __builtin_strchr(s, c); 245 } 246 247 return __strchr_chk(s, c, bos); 248} 249 250__BIONIC_FORTIFY_INLINE 251char* strrchr(const char* const _Nonnull s __pass_object_size, int c) 252 __overloadable { 253 size_t bos = __bos(s); 254 255 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 256 return __builtin_strrchr(s, c); 257 } 258 259 return __strrchr_chk(s, c, bos); 260} 261#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ 262 263#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 264/* In *many* cases, memset(foo, sizeof(foo), 0) is a mistake where the user has 265 * flipped the size + value arguments. However, there may be cases (e.g. with 266 * macros) where it's okay for the size to fold to zero. We should warn on this, 267 * but we should also provide a FORTIFY'ed escape hatch. 268 */ 269__BIONIC_ERROR_FUNCTION_VISIBILITY 270void* memset(void* _Nonnull s, int c, size_t n, struct __bionic_zero_size_is_okay_t ok) 271 __overloadable 272 __error_if_overflows_dst(memset, s, n, "size"); 273 274__BIONIC_FORTIFY_INLINE 275void* memset(void* const _Nonnull s __pass_object_size0, int c, size_t n, struct __bionic_zero_size_is_okay_t ok __attribute__((unused))) 276 __overloadable { 277 return __builtin___memset_chk(s, c, n, __bos0(s)); 278} 279 280extern struct __bionic_zero_size_is_okay_t __bionic_zero_size_is_okay; 281/* We verify that `c` is non-zero, because as pointless as memset(foo, 0, 0) is, 282 * flipping size + count will do nothing. 283 */ 284__BIONIC_ERROR_FUNCTION_VISIBILITY 285void* memset(void* _Nonnull s, int c, size_t n) __overloadable 286 __enable_if(c && !n, "selected when we'll set zero bytes") 287 __RENAME_CLANG(memset) 288 __warnattr_real("will set 0 bytes; maybe the arguments got flipped? " 289 "(Add __bionic_zero_size_is_okay as a fourth argument " 290 "to silence this.)"); 291#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 292 293#undef __error_zero_size 294#undef __error_if_overflows_dst 295#else // defined(__clang__) 296extern char* __strncpy_real(char*, const char*, size_t) __RENAME(strncpy); 297extern void* __memrchr_real(const void*, int, size_t) __RENAME(memrchr); 298extern size_t __strlcpy_real(char*, const char*, size_t) 299 __RENAME(strlcpy); 300extern size_t __strlcat_real(char*, const char*, size_t) 301 __RENAME(strlcat); 302 303__errordecl(__memchr_buf_size_error, "memchr called with size bigger than buffer"); 304__errordecl(__memrchr_buf_size_error, "memrchr called with size bigger than buffer"); 305 306#if __ANDROID_API__ >= __ANDROID_API_M__ 307__BIONIC_FORTIFY_INLINE 308void* memchr(const void *_Nonnull s __pass_object_size, int c, size_t n) { 309 size_t bos = __bos(s); 310 311 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 312 return __builtin_memchr(s, c, n); 313 } 314 315 if (__builtin_constant_p(n) && (n > bos)) { 316 __memchr_buf_size_error(); 317 } 318 319 if (__builtin_constant_p(n) && (n <= bos)) { 320 return __builtin_memchr(s, c, n); 321 } 322 323 return __memchr_chk(s, c, n, bos); 324} 325 326__BIONIC_FORTIFY_INLINE 327void* memrchr(const void* s, int c, size_t n) { 328 size_t bos = __bos(s); 329 330 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 331 return __memrchr_real(s, c, n); 332 } 333 334 if (__builtin_constant_p(n) && (n > bos)) { 335 __memrchr_buf_size_error(); 336 } 337 338 if (__builtin_constant_p(n) && (n <= bos)) { 339 return __memrchr_real(s, c, n); 340 } 341 342 return __memrchr_chk(s, c, n, bos); 343} 344#endif /* __ANDROID_API__ >= __ANDROID_API_M__ */ 345 346#if __ANDROID_API__ >= __ANDROID_API_L__ 347__BIONIC_FORTIFY_INLINE 348char* stpncpy(char* _Nonnull dst, const char* _Nonnull src, size_t n) { 349 size_t bos_dst = __bos(dst); 350 size_t bos_src = __bos(src); 351 352 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 353 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 354 } 355 356 if (__builtin_constant_p(n) && (n <= bos_src)) { 357 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 358 } 359 360 size_t slen = __builtin_strlen(src); 361 if (__builtin_constant_p(slen)) { 362 return __builtin___stpncpy_chk(dst, src, n, bos_dst); 363 } 364 365 return __stpncpy_chk2(dst, src, n, bos_dst, bos_src); 366} 367 368__BIONIC_FORTIFY_INLINE 369char* strncpy(char* _Nonnull dst, const char* _Nonnull src, size_t n) { 370 size_t bos_dst = __bos(dst); 371 size_t bos_src = __bos(src); 372 373 if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 374 return __strncpy_real(dst, src, n); 375 } 376 377 if (__builtin_constant_p(n) && (n <= bos_src)) { 378 return __builtin___strncpy_chk(dst, src, n, bos_dst); 379 } 380 381 size_t slen = __builtin_strlen(src); 382 if (__builtin_constant_p(slen)) { 383 return __builtin___strncpy_chk(dst, src, n, bos_dst); 384 } 385 386 return __strncpy_chk2(dst, src, n, bos_dst, bos_src); 387} 388#endif /* __ANDROID_API__ >= __ANDROID_API_L__ */ 389 390#if __ANDROID_API__ >= __ANDROID_API_J_MR1__ 391__BIONIC_FORTIFY_INLINE 392size_t strlcpy(char* _Nonnull dst __pass_object_size, const char* _Nonnull src, size_t size) { 393 size_t bos = __bos(dst); 394 395 // Compiler doesn't know destination size. Don't call __strlcpy_chk 396 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 397 return __strlcpy_real(dst, src, size); 398 } 399 400 // Compiler can prove, at compile time, that the passed in size 401 // is always <= the actual object size. Don't call __strlcpy_chk 402 if (__builtin_constant_p(size) && (size <= bos)) { 403 return __strlcpy_real(dst, src, size); 404 } 405 406 return __strlcpy_chk(dst, src, size, bos); 407} 408 409__BIONIC_FORTIFY_INLINE 410size_t strlcat(char* _Nonnull dst, const char* _Nonnull src, size_t size) { 411 size_t bos = __bos(dst); 412 413 // Compiler doesn't know destination size. Don't call __strlcat_chk 414 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 415 return __strlcat_real(dst, src, size); 416 } 417 418 // Compiler can prove, at compile time, that the passed in size 419 // is always <= the actual object size. Don't call __strlcat_chk 420 if (__builtin_constant_p(size) && (size <= bos)) { 421 return __strlcat_real(dst, src, size); 422 } 423 424 return __strlcat_chk(dst, src, size, bos); 425} 426 427__BIONIC_FORTIFY_INLINE 428size_t strlen(const char* _Nonnull s) __overloadable { 429 size_t bos = __bos(s); 430 431 // Compiler doesn't know destination size. Don't call __strlen_chk 432 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 433 return __builtin_strlen(s); 434 } 435 436 size_t slen = __builtin_strlen(s); 437 if (__builtin_constant_p(slen)) { 438 return slen; 439 } 440 441 return __strlen_chk(s, bos); 442} 443#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */ 444 445#if __ANDROID_API__ >= __ANDROID_API_J_MR2__ 446__BIONIC_FORTIFY_INLINE 447char* strchr(const char* _Nonnull s, int c) { 448 size_t bos = __bos(s); 449 450 // Compiler doesn't know destination size. Don't call __strchr_chk 451 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 452 return __builtin_strchr(s, c); 453 } 454 455 size_t slen = __builtin_strlen(s); 456 if (__builtin_constant_p(slen) && (slen < bos)) { 457 return __builtin_strchr(s, c); 458 } 459 460 return __strchr_chk(s, c, bos); 461} 462 463__BIONIC_FORTIFY_INLINE 464char* strrchr(const char* _Nonnull s, int c) { 465 size_t bos = __bos(s); 466 467 // Compiler doesn't know destination size. Don't call __strrchr_chk 468 if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) { 469 return __builtin_strrchr(s, c); 470 } 471 472 size_t slen = __builtin_strlen(s); 473 if (__builtin_constant_p(slen) && (slen < bos)) { 474 return __builtin_strrchr(s, c); 475 } 476 477 return __strrchr_chk(s, c, bos); 478} 479#endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */ 480#endif /* defined(__clang__) */ 481#endif /* defined(__BIONIC_FORTIFY) */ 482