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 23extern "C" { 24#endif 25 26void *__memchr_chk(const void* s, int c, size_t n, size_t actual_size); 27void *__memrchr_chk(const void*, int, size_t, size_t); 28size_t __strlcpy_chk(char*, const char*, size_t, size_t); 29size_t __strlcat_chk(char*, const char*, size_t, size_t); 30char *__strchr_chk(const char* p, int ch, size_t s_len); 31char *__strrchr_chk(const char *p, int ch, size_t s_len); 32size_t __strlen_chk(const char* s, size_t s_len); 33 34#ifdef __FORTIFY_COMPILATION 35__DIAGNOSE_FORTIFY_INLINE 36char *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 49char *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 62void *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 73void *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 86char *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 100char *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 109char *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 120char *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 131void *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 140size_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 153size_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 167void *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 180void *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 191extern void* __memrchr_real(const void*, int, size_t) __DIAGNOSE_RENAME(memrchr); 192 193#ifdef __FORTIFY_RUNTIME 194__DIAGNOSE_FORTIFY_INLINE 195void *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 207char* 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 221char* 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 236size_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