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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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