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