string.h (5478B)
1 /* 2 * Copyright (C) 2015-2016 Dimitris Papastamos <sin@2f30.org> 3 * Copyright (C) 2022 q66 <q66@chimera-linux.org> 4 * 5 * Permission to use, copy, modify, and/or distribute this software for any 6 * purpose with or without fee is hereby granted. 7 * 8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 15 */ 16 17 #ifndef _FORTIFY_STRING_H 18 #define _FORTIFY_STRING_H 19 20 #if !defined(__cplusplus) && !defined(__clang__) 21 __extension__ 22 #endif 23 #include_next <string.h> 24 25 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 26 #include "fortify-headers.h" 27 28 #ifdef __cplusplus 29 extern "C" { 30 #endif 31 32 #undef memcpy 33 #undef memmove 34 #undef memset 35 #undef strcat 36 #undef strcpy 37 #undef strncat 38 #undef strncpy 39 40 __access(write_only, 1, 3) 41 __access(read_only, 2, 3) 42 _FORTIFY_FN(memcpy) void *memcpy(void * _FORTIFY_POS0 __od, 43 const void * _FORTIFY_POS0 __os, size_t __n) 44 { 45 size_t __bd = __bos(__od, 0); 46 size_t __bs = __bos(__os, 0); 47 char *__d = (char *)__od; 48 const char *__s = (const char *)__os; 49 50 /* trap if pointers are overlapping but not if dst == src. 51 * gcc seems to like to generate code that relies on dst == src */ 52 if ((__d < __s && __d + __n > __s) || 53 (__s < __d && __s + __n > __d)) 54 __builtin_trap(); 55 if (__n > __bd || __n > __bs) 56 __builtin_trap(); 57 return __builtin_memcpy(__od, __os, __n); 58 } 59 60 __access(write_only, 1, 3) 61 __access(read_only, 2, 3) 62 _FORTIFY_FN(memmove) void *memmove(void * _FORTIFY_POS0 __d, 63 const void * _FORTIFY_POS0 __s, size_t __n) 64 { 65 size_t __bd = __bos(__d, 0); 66 size_t __bs = __bos(__s, 0); 67 68 if (__n > __bd || __n > __bs) 69 __builtin_trap(); 70 return __orig_memmove(__d, __s, __n); 71 } 72 73 __access(write_only, 1, 3) 74 __warning_if(__c != 0 && __n == 0, "'memset' will set `0` bytes; did you invert the arguments?") 75 _FORTIFY_FN(memset) void *memset(void * _FORTIFY_POS0 __d, int __c, size_t __n) 76 { 77 size_t __b = __bos(__d, 0); 78 79 if (__n > __b) 80 __builtin_trap(); 81 return __builtin_memset(__d, __c, __n); 82 } 83 84 #if defined(_POSIX_SOURCE) || defined(_POSIX_C_SOURCE) \ 85 || defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) \ 86 || defined(_BSD_SOURCE) 87 #undef stpcpy 88 __access(write_only, 1) 89 __access(read_only, 2) 90 _FORTIFY_FN(stpcpy) char *stpcpy(char * _FORTIFY_POS0 __d, const char *__s) 91 { 92 size_t __b = __bos(__d, 0); 93 94 if (strlen(__s) + 1 > __b) 95 __builtin_trap(); 96 return __orig_stpcpy(__d, __s); 97 } 98 99 #undef stpncpy 100 __access(write_only, 1) 101 __access(read_only, 2) 102 _FORTIFY_FN(stpncpy) char *stpncpy(char * _FORTIFY_POS0 __d, const char *__s, 103 size_t __n) 104 { 105 size_t __b = __bos(__d, 0); 106 107 if (__n > __b && strlen(__s) + 1 > __b) 108 __builtin_trap(); 109 return __orig_stpncpy(__d, __s, __n); 110 } 111 #endif 112 113 __access(read_write, 1) 114 __access(read_only, 2) 115 _FORTIFY_FN(strcat) char *strcat(char * _FORTIFY_POS0 __d, const char *__s) 116 { 117 size_t __b = __bos(__d, 0); 118 119 if (strlen(__s) + strlen(__d) + 1 > __b) 120 __builtin_trap(); 121 return __orig_strcat(__d, __s); 122 } 123 124 __access(write_only, 1) 125 __access(read_only, 2) 126 _FORTIFY_FN(strcpy) char *strcpy(char * _FORTIFY_POS0 __d, const char *__s) 127 { 128 size_t __b = __bos(__d, 0); 129 130 if (strlen(__s) + 1 > __b) 131 __builtin_trap(); 132 return __orig_strcpy(__d, __s); 133 } 134 135 __access(read_write, 1) 136 __access(read_only, 2) 137 _FORTIFY_FN(strncat) char *strncat(char * _FORTIFY_POS0 __d, const char *__s, 138 size_t __n) 139 { 140 size_t __b = __bos(__d, 0); 141 size_t __sl, __dl; 142 143 if (__n > __b) { 144 __sl = strlen(__s); 145 __dl = strlen(__d); 146 if (__sl > __n) 147 __sl = __n; 148 if (__sl + __dl + 1 > __b) 149 __builtin_trap(); 150 } 151 return __orig_strncat(__d, __s, __n); 152 } 153 154 __access(write_only, 1) 155 __access(read_only, 2) 156 _FORTIFY_FN(strncpy) char *strncpy(char * _FORTIFY_POS0 __d, 157 const char *__s, size_t __n) 158 { 159 size_t __b = __bos(__d, 0); 160 161 if (__n > __b) 162 __builtin_trap(); 163 return __orig_strncpy(__d, __s, __n); 164 } 165 166 #ifdef _GNU_SOURCE 167 #undef mempcpy 168 __access(write_only, 1, 3) 169 __access(read_only, 2, 3) 170 _FORTIFY_FN(mempcpy) void *mempcpy(void * _FORTIFY_POS0 __d, 171 const void * _FORTIFY_POS0 __s, size_t __n) 172 { 173 size_t __bd = __bos(__d, 0); 174 size_t __bs = __bos(__s, 0); 175 176 if (__n > __bd || __n > __bs) 177 __builtin_trap(); 178 return __orig_mempcpy(__d, __s, __n); 179 } 180 #endif 181 182 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) 183 #undef strlcat 184 #undef strlcpy 185 __access(read_write, 1) 186 __access(read_only, 2) 187 _FORTIFY_FN(strlcat) size_t strlcat(char * _FORTIFY_POS0 __d, 188 const char *__s, size_t __n) 189 { 190 size_t __b = __bos(__d, 0); 191 192 if (__n > __b) 193 __builtin_trap(); 194 return __orig_strlcat(__d, __s, __n); 195 } 196 197 __access(write_only, 1) 198 __access(read_only, 2) 199 _FORTIFY_FN(strlcpy) size_t strlcpy(char * _FORTIFY_POS0 __d, 200 const char *__s, size_t __n) 201 { 202 size_t __b = __bos(__d, 0); 203 204 if (__n > __b) 205 __builtin_trap(); 206 return __orig_strlcpy(__d, __s, __n); 207 } 208 #endif 209 210 #ifdef __cplusplus 211 } 212 #endif 213 214 #endif 215 216 #endif