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 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
     44 __BIONIC_FORTIFY_INLINE
     45 void* memcpy(void* const dst __pass_object_size0, const void* src, size_t copy_amount)
     46         __overloadable
     47         __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < copy_amount,
     48                          "'memcpy' called with size bigger than buffer") {
     49     return __builtin___memcpy_chk(dst, src, copy_amount, __bos0(dst));
     50 }
     51 
     52 __BIONIC_FORTIFY_INLINE
     53 void* memmove(void* const dst __pass_object_size0, const void* src, size_t len)
     54         __overloadable
     55         __clang_error_if(__bos0(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(dst) < len,
     56                          "'memmove' called with size bigger than buffer") {
     57     return __builtin___memmove_chk(dst, src, len, __bos0(dst));
     58 }
     59 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
     60 
     61 #if __ANDROID_API__ >= __ANDROID_API_L__
     62 __BIONIC_FORTIFY_INLINE
     63 char* stpcpy(char* const dst __pass_object_size, const char* src)
     64         __overloadable
     65         __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
     66                              __bos(dst) <= __builtin_strlen(src),
     67                          "'stpcpy' called with string bigger than buffer") {
     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
     74 char* strcpy(char* const dst __pass_object_size, const char* src)
     75         __overloadable
     76         __clang_error_if(__bos(dst) != __BIONIC_FORTIFY_UNKNOWN_SIZE &&
     77                              __bos(dst) <= __builtin_strlen(src),
     78                          "'strcpy' called with string bigger than buffer") {
     79     return __builtin___strcpy_chk(dst, src, __bos(dst));
     80 }
     81 
     82 __BIONIC_FORTIFY_INLINE
     83 char* strcat(char* const dst __pass_object_size, const char* src) __overloadable {
     84     return __builtin___strcat_chk(dst, src, __bos(dst));
     85 }
     86 
     87 __BIONIC_FORTIFY_INLINE
     88 char* strncat(char* const dst __pass_object_size, const char* src, size_t n) __overloadable {
     89     return __builtin___strncat_chk(dst, src, n, __bos(dst));
     90 }
     91 
     92 __BIONIC_FORTIFY_INLINE
     93 void* memset(void* const s __pass_object_size0, int c, size_t n)
     94         __overloadable
     95         __clang_error_if(__bos0(s) != __BIONIC_FORTIFY_UNKNOWN_SIZE && __bos0(s) < n,
     96                          "'memset' called with size bigger than buffer")
     97         /* If you're a user who wants this warning to go away: use `(&memset)(foo, bar, baz)`. */
     98         __clang_warning_if(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") {
     99     return __builtin___memset_chk(s, c, n, __bos0(s));
    100 }
    101 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    102 
    103 #if __ANDROID_API__ >= __ANDROID_API_M__
    104 __BIONIC_FORTIFY_INLINE
    105 void* memchr(const void* const s __pass_object_size, int c, size_t n) __overloadable {
    106     size_t bos = __bos(s);
    107 
    108     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    109         return __builtin_memchr(s, c, n);
    110     }
    111 
    112     return __memchr_chk(s, c, n, bos);
    113 }
    114 
    115 __BIONIC_FORTIFY_INLINE
    116 void* __memrchr_fortify(const void* const __pass_object_size s, int c, size_t n) __overloadable {
    117     size_t bos = __bos(s);
    118 
    119     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    120         return __memrchr_real(s, c, n);
    121     }
    122 
    123     return __memrchr_chk(s, c, n, bos);
    124 }
    125 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
    126 
    127 #if __ANDROID_API__ >= __ANDROID_API_L__
    128 __BIONIC_FORTIFY_INLINE
    129 char* stpncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
    130         __overloadable {
    131     size_t bos_dst = __bos(dst);
    132     size_t bos_src = __bos(src);
    133 
    134     /* Ignore dst size checks; they're handled in strncpy_chk */
    135     if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    136         return __builtin___stpncpy_chk(dst, src, n, bos_dst);
    137     }
    138 
    139     return __stpncpy_chk2(dst, src, n, bos_dst, bos_src);
    140 }
    141 
    142 __BIONIC_FORTIFY_INLINE
    143 char* strncpy(char* const dst __pass_object_size, const char* const src __pass_object_size, size_t n)
    144         __overloadable {
    145     size_t bos_dst = __bos(dst);
    146     size_t bos_src = __bos(src);
    147 
    148     /* Ignore dst size checks; they're handled in strncpy_chk */
    149     if (bos_src == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    150         return __builtin___strncpy_chk(dst, src, n, bos_dst);
    151     }
    152 
    153     return __strncpy_chk2(dst, src, n, bos_dst, bos_src);
    154 }
    155 #endif /* __ANDROID_API__ >= __ANDROID_API_L__ */
    156 
    157 #if __ANDROID_API__ >= __ANDROID_API_J_MR1__
    158 __BIONIC_FORTIFY_INLINE
    159 size_t strlcpy(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
    160     size_t bos = __bos(dst);
    161 
    162     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    163         return __call_bypassing_fortify(strlcpy)(dst, src, size);
    164     }
    165 
    166     return __strlcpy_chk(dst, src, size, bos);
    167 }
    168 
    169 __BIONIC_FORTIFY_INLINE
    170 size_t strlcat(char* const dst __pass_object_size, const char* src, size_t size) __overloadable {
    171     size_t bos = __bos(dst);
    172 
    173     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    174         return __call_bypassing_fortify(strlcat)(dst, src, size);
    175     }
    176 
    177     return __strlcat_chk(dst, src, size, bos);
    178 }
    179 
    180 /*
    181  * If we can evaluate the size of s at compile-time, just call __builtin_strlen
    182  * on it directly. This makes it way easier for compilers to fold things like
    183  * strlen("Foo") into a constant, as users would expect. -1ULL is chosen simply
    184  * because it's large.
    185  */
    186 __BIONIC_FORTIFY_INLINE
    187 size_t strlen(const char* const s __pass_object_size)
    188         __overloadable __enable_if(__builtin_strlen(s) != -1ULL,
    189                                    "enabled if s is a known good string.") {
    190     return __builtin_strlen(s);
    191 }
    192 
    193 __BIONIC_FORTIFY_INLINE
    194 size_t strlen(const char* const s __pass_object_size0) __overloadable {
    195     size_t bos = __bos0(s);
    196 
    197     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    198         return __builtin_strlen(s);
    199     }
    200 
    201     return __strlen_chk(s, bos);
    202 }
    203 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR1__ */
    204 
    205 #if  __ANDROID_API__ >= __ANDROID_API_J_MR2__
    206 __BIONIC_FORTIFY_INLINE
    207 char* strchr(const char* const s __pass_object_size, int c) __overloadable {
    208     size_t bos = __bos(s);
    209 
    210     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    211         return __builtin_strchr(s, c);
    212     }
    213 
    214     return __strchr_chk(s, c, bos);
    215 }
    216 
    217 __BIONIC_FORTIFY_INLINE
    218 char* strrchr(const char* const s __pass_object_size, int c) __overloadable {
    219     size_t bos = __bos(s);
    220 
    221     if (bos == __BIONIC_FORTIFY_UNKNOWN_SIZE) {
    222         return __builtin_strrchr(s, c);
    223     }
    224 
    225     return __strrchr_chk(s, c, bos);
    226 }
    227 #endif /* __ANDROID_API__ >= __ANDROID_API_J_MR2__ */
    228 
    229 #if __ANDROID_API__ >= __ANDROID_API_M__
    230 #if defined(__cplusplus)
    231 extern "C++" {
    232 __BIONIC_FORTIFY_INLINE
    233 void* memrchr(void* const __pass_object_size s, int c, size_t n) {
    234     return __memrchr_fortify(s, c, n);
    235 }
    236 
    237 __BIONIC_FORTIFY_INLINE
    238 const void* memrchr(const void* const __pass_object_size s, int c, size_t n) {
    239     return __memrchr_fortify(s, c, n);
    240 }
    241 }
    242 #else
    243 __BIONIC_FORTIFY_INLINE
    244 void* memrchr(const void* const __pass_object_size s, int c, size_t n) __overloadable {
    245     return __memrchr_fortify(s, c, n);
    246 }
    247 #endif
    248 #endif /* __ANDROID_API__ >= __ANDROID_API_M__ */
    249 
    250 #endif /* defined(__BIONIC_FORTIFY) */
    251