Home | History | Annotate | Download | only in fortify
      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