1 /* 2 * Copyright (c) 2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #ifndef _STRING_H 17 #error "Never include this file directly; instead, include <string.h>" 18 #endif 19 20 #include "fortify.h" 21 22 #ifdef __cplusplus 23 extern "C" { 24 #endif 25 26 void *__memchr_chk(const void* s, int c, size_t n, size_t actual_size); 27 void *__memrchr_chk(const void*, int, size_t, size_t); 28 size_t __strlcpy_chk(char*, const char*, size_t, size_t); 29 size_t __strlcat_chk(char*, const char*, size_t, size_t); 30 char *__strchr_chk(const char* p, int ch, size_t s_len); 31 char *__strrchr_chk(const char *p, int ch, size_t s_len); 32 size_t __strlen_chk(const char* s, size_t s_len); 33 34 #ifdef __FORTIFY_COMPILATION 35 __DIAGNOSE_FORTIFY_INLINE 36 char *strcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src) 37 __DIAGNOSE_OVERLOAD 38 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)), 39 "'strcpy' " CALLED_WITH_STRING_BIGGER_BUFFER) 40 { 41 #ifdef __FORTIFY_RUNTIME 42 return __builtin___strcpy_chk(dest, src, __DIAGNOSE_BOS(dest)); 43 #else 44 return __builtin_strcpy(dest, src); 45 #endif 46 } 47 48 __DIAGNOSE_FORTIFY_INLINE 49 char *stpcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src) 50 __DIAGNOSE_OVERLOAD 51 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)), 52 "'stpcpy' " CALLED_WITH_STRING_BIGGER_BUFFER) 53 { 54 #ifdef __FORTIFY_RUNTIME 55 return __builtin___stpcpy_chk(dest, src, __DIAGNOSE_BOS(dest)); 56 #else 57 return __builtin_stpcpy(dest, src); 58 #endif 59 } 60 61 __DIAGNOSE_FORTIFY_INLINE 62 void *memmove(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE0, const void *src, size_t len) 63 __DIAGNOSE_OVERLOAD 64 { 65 #ifdef __FORTIFY_RUNTIME 66 return __builtin___memmove_chk(dest, src, len, __DIAGNOSE_BOS(dest)); 67 #else 68 return __builtin_memmove(dest, src, len); 69 #endif 70 } 71 72 __DIAGNOSE_FORTIFY_INLINE 73 void *mempcpy(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const void *src, size_t copy_amount) 74 __DIAGNOSE_OVERLOAD 75 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS0(dest), copy_amount), 76 "'mempcpy' " CALLED_WITH_STRING_BIGGER_BUFFER) 77 { 78 #ifdef __FORTIFY_RUNTIME 79 return __builtin___mempcpy_chk(dest, src, copy_amount, __DIAGNOSE_BOS0(dest)); 80 #else 81 return __builtin_mempcpy(dest, src, copy_amount); 82 #endif 83 } 84 85 __DIAGNOSE_FORTIFY_INLINE 86 char *strcat(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src) 87 __DIAGNOSE_OVERLOAD 88 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LE(__DIAGNOSE_BOS(dest), __builtin_strlen(src)), 89 "'strcat' " CALLED_WITH_STRING_BIGGER_BUFFER) 90 { 91 #ifdef __FORTIFY_RUNTIME 92 return __builtin___strcat_chk(dest, src, __DIAGNOSE_BOS(dest)); 93 #else 94 return __builtin_strcat(dest, src); 95 #endif 96 } 97 98 #ifdef __FORTIFY_RUNTIME 99 __DIAGNOSE_FORTIFY_INLINE 100 char *strncat(char* const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t n) 101 __DIAGNOSE_OVERLOAD 102 { 103 return __builtin___strncat_chk(dest, src, n, __DIAGNOSE_BOS(dest)); 104 } 105 #endif 106 107 #ifdef __FORTIFY_RUNTIME 108 __DIAGNOSE_FORTIFY_INLINE 109 char *stpncpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, 110 const char *const src __DIAGNOSE_PASS_OBJECT_SIZE, size_t n) 111 __DIAGNOSE_OVERLOAD 112 { 113 size_t bos_dest = __DIAGNOSE_BOS(dest); 114 return __builtin___stpncpy_chk(dest, src, n, bos_dest); 115 } 116 #endif 117 118 #ifdef __FORTIFY_RUNTIME 119 __DIAGNOSE_FORTIFY_INLINE 120 char *strncpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, 121 const char *const src __DIAGNOSE_PASS_OBJECT_SIZE, size_t n) 122 __DIAGNOSE_OVERLOAD 123 { 124 size_t bos_dest = __DIAGNOSE_BOS(dest); 125 return __builtin___strncpy_chk(dest, src, n, bos_dest); 126 } 127 #endif 128 129 #ifdef __FORTIFY_RUNTIME 130 __DIAGNOSE_FORTIFY_INLINE 131 void *memcpy(void *const dest __DIAGNOSE_PASS_OBJECT_SIZE0, const void *src, size_t copy_amount) 132 __DIAGNOSE_OVERLOAD 133 { 134 return __builtin___memcpy_chk(dest, src, copy_amount, __DIAGNOSE_BOS0(dest)); 135 } 136 #endif 137 138 #if defined(_BSD_SOURCE) || defined(_GNU_SOURCE) 139 __DIAGNOSE_FORTIFY_INLINE 140 size_t strlcpy(char *const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char *src, size_t size) 141 __DIAGNOSE_OVERLOAD 142 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size), 143 "'strlcpy' called with size bigger than buffer") 144 { 145 #ifdef __FORTIFY_RUNTIME 146 return __strlcpy_chk(dest, src, size, __DIAGNOSE_BOS(dest)); 147 #else 148 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlcpy)(dest, src, size); 149 #endif 150 } 151 152 __DIAGNOSE_FORTIFY_INLINE 153 size_t strlcat(char* const dest __DIAGNOSE_PASS_OBJECT_SIZE, const char* src, size_t size) 154 __DIAGNOSE_OVERLOAD 155 __DIAGNOSE_ERROR_IF(__DIAGNOSE_UNEVALUATED_LT(__DIAGNOSE_BOS(dest), size), 156 "'strlcat' called with size bigger than buffer") 157 { 158 #ifdef __FORTIFY_RUNTIME 159 return __strlcat_chk(dest, src, size, __DIAGNOSE_BOS(dest)); 160 #else 161 return __DIAGNOSE_CALL_BYPASSING_FORTIFY(strlcat)(dest, src, size); 162 #endif 163 } 164 #endif // defined(_GNU_SOURCE) || defined(_BSD_SOURCE) 165 166 __DIAGNOSE_FORTIFY_INLINE 167 void *memset(void *const s __DIAGNOSE_PASS_OBJECT_SIZE0, int c, size_t n) 168 __DIAGNOSE_OVERLOAD 169 __DIAGNOSE_WARNING_IF(c && !n, "'memset' will set 0 bytes; maybe the arguments got flipped?") 170 { 171 #ifdef __FORTIFY_RUNTIME 172 return __builtin___memset_chk(s, c, n, __DIAGNOSE_BOS0(s)); 173 #else 174 return __builtin_memset(s, c, n); 175 #endif 176 } 177 178 #ifdef __FORTIFY_RUNTIME 179 __DIAGNOSE_FORTIFY_INLINE 180 void *memchr(const void *const s __DIAGNOSE_PASS_OBJECT_SIZE, int c, size_t n) 181 __DIAGNOSE_OVERLOAD 182 { 183 size_t bos = __DIAGNOSE_BOS(s); 184 if (__DIAGNOSE_BOS_TRIVIALLY_GE(bos, n)) { 185 return __builtin_memchr(s, c, n); 186 } 187 return __memchr_chk(s, c, n, bos); 188 } 189 #endif // memchr __FORTIFY_RUNTIME 190 191 extern void* __memrchr_real(const void*, int, size_t) __DIAGNOSE_RENAME(memrchr); 192 193 #ifdef __FORTIFY_RUNTIME 194 __DIAGNOSE_FORTIFY_INLINE 195 void *memrchr(const void *const __DIAGNOSE_PASS_OBJECT_SIZE s, int c, size_t n) 196 __DIAGNOSE_OVERLOAD 197 { 198 size_t bos = __DIAGNOSE_BOS(s); 199 if (__DIAGNOSE_BOS_TRIVIALLY_GE(bos, n)) { 200 return __memrchr_real(s, c, n); 201 } 202 return __memrchr_chk(s, c, n, bos); 203 } 204 #endif 205 206 __DIAGNOSE_FORTIFY_INLINE 207 char* strchr(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE, int c) 208 __DIAGNOSE_OVERLOAD 209 { 210 #ifdef __FORTIFY_RUNTIME 211 size_t bos = __DIAGNOSE_BOS(s); 212 213 if (bos != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE) { 214 return __strchr_chk(s, c, bos); 215 } 216 #endif 217 return __builtin_strchr(s, c); 218 } 219 220 __DIAGNOSE_FORTIFY_INLINE 221 char* strrchr(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE, int c) 222 __DIAGNOSE_OVERLOAD 223 { 224 #ifdef __FORTIFY_RUNTIME 225 size_t bos = __DIAGNOSE_BOS(s); 226 227 if (bos != __DIAGNOSE_FORTIFY_UNKNOWN_SIZE) { 228 return __strrchr_chk(s, c, bos); 229 } 230 #endif 231 return __builtin_strrchr(s, c); 232 } 233 234 #ifdef __FORTIFY_RUNTIME 235 __DIAGNOSE_FORTIFY_INLINE 236 size_t strlen(const char* const s __DIAGNOSE_PASS_OBJECT_SIZE0) 237 __DIAGNOSE_OVERLOAD 238 { 239 return __strlen_chk(s, __DIAGNOSE_BOS0(s)); 240 } 241 #endif 242 243 #endif // __FORTIFY_COMPILATION 244 #ifdef __cplusplus 245 } 246 #endif