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