stdlib.h (4681B)
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_STDLIB_H 18 #define _FORTIFY_STDLIB_H 19 20 #if !defined(__cplusplus) && !defined(__clang__) 21 __extension__ 22 #endif 23 #include_next <stdlib.h> 24 25 #if defined(_FORTIFY_SOURCE) && _FORTIFY_SOURCE > 0 && defined(__OPTIMIZE__) && __OPTIMIZE__ > 0 26 27 #include "fortify-headers.h" 28 29 #ifdef __cplusplus 30 extern "C" { 31 #endif 32 33 #undef mbstowcs 34 #if __has_builtin(__builtin_mbstowcs) 35 __diagnose_as_builtin(__builtin_mbstowcs, 1, 2, 3) 36 #endif 37 _FORTIFY_FN(mbstowcs) size_t mbstowcs(wchar_t * _FORTIFY_POS0 __ws, 38 const char *__s, size_t __wn) 39 { 40 __fh_size_t __b = __fh_bos(__ws, 0); 41 42 if (__ws && __wn > __b / sizeof(wchar_t)) 43 __builtin_trap(); 44 return __orig_mbstowcs(__ws, __s, __wn); 45 } 46 47 #undef wcstombs 48 __fh_access(write_only, 1, 3) 49 #if __has_builtin(__builtin_wcstombs) 50 __diagnose_as_builtin(__builtin_wcstombs, 1, 2, 3) 51 #endif 52 _FORTIFY_FN(wcstombs) size_t wcstombs(char * _FORTIFY_POS0 __s, 53 const wchar_t *__ws, size_t __n) 54 { 55 __fh_size_t __b = __fh_bos(__s, 0); 56 57 if (__s && __n > __b) 58 __builtin_trap(); 59 return __orig_wcstombs(__s, __ws, __n); 60 } 61 62 #if 0 63 /* https://github.com/jvoisin/fortify-headers/issues/24 */ 64 #ifdef MB_CUR_MAX 65 #undef wctomb 66 #if __has_builtin(__builtin_wctomb) 67 __diagnose_as_builtin(__builtin_wctomb, 1, 2) 68 #endif 69 _FORTIFY_FN(wctomb) int wctomb(char * _FORTIFY_POS0 __s, wchar_t __w) 70 { 71 __fh_size_t __b = __fh_bos(__s, 0); 72 73 if (__s && 16 > __b && MB_CUR_MAX > __b) 74 __builtin_trap(); 75 return __orig_wctomb(__s, __w); 76 } 77 #endif // MB_CUR_MAX 78 #endif 79 80 #undef qsort 81 #if __has_builtin(__builtin_qsort) 82 __diagnose_as_builtin(__builtin_qsort, 1, 2, 3, 4) 83 #endif 84 __fh_access(read_write, 1) 85 _FORTIFY_FN(qsort) void qsort(void * _FORTIFY_POS0 base, size_t nmemb, size_t size, 86 int (*compar)(const void *, const void *)) 87 { 88 __fh_size_t __b = __fh_bos(base, 0); 89 90 if (__bmo(nmemb, size)) 91 __builtin_trap(); 92 if (nmemb * size> __b) 93 __builtin_trap(); 94 95 return __orig_qsort(base, nmemb, size, compar); 96 } 97 98 /* FIXME clang */ 99 #if !defined(__clang__) 100 #undef malloc 101 #undef realloc 102 #undef calloc 103 104 __fh_malloc(malloc (free, 1)) 105 __fh_alloc_size(1) 106 __warn_unused_result 107 #if __has_builtin(__builtin_malloc) 108 __diagnose_as_builtin(__builtin_malloc, 1) 109 #endif 110 _FORTIFY_FN(malloc) void *malloc(size_t __s) 111 { 112 return __orig_malloc(__s); 113 } 114 115 __fh_alloc_size(2) 116 __warn_unused_result 117 #if __has_builtin(__builtin_realloc) 118 __diagnose_as_builtin(__builtin_realloc, 1, 2) 119 #endif 120 _FORTIFY_FN(realloc) void *realloc(void *__p, size_t __s) 121 { 122 return __orig_realloc(__p, __s); 123 } 124 125 __fh_alloc_size(1, 2) 126 __warn_unused_result 127 #if __has_builtin(__builtin_calloc) 128 __diagnose_as_builtin(__builtin_calloc, 1, 2) 129 #endif 130 _FORTIFY_FN(calloc) void *calloc(size_t __n, size_t __s) 131 { 132 return __orig_calloc(__n, __s); 133 } 134 135 #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) 136 #undef reallocarray 137 __fh_alloc_size (2, 3) 138 __warn_unused_result 139 #if __has_builtin(__builtin_reallocarray) 140 __diagnose_as_builtin(__builtin_reallocarray, 1, 2, 3) 141 #endif 142 _FORTIFY_FN(reallocarray) void* reallocarray(void* __p, size_t __n, size_t __s) 143 { 144 return __orig_reallocarray(__p, __n, __s); 145 } 146 #endif 147 148 #if (defined(_XOPEN_SOURCE) || defined(_GNU_SOURCE) || defined(_BSD_SOURCE)) 149 #undef realpath 150 __warning_if(__p == NULL, "'realpath' called with path set to `NULL`; did you invert the arguments?") 151 #if __has_builtin(__builtin_realpath) 152 __diagnose_as_builtin(__builtin_realpath, 1, 2) 153 #endif 154 _FORTIFY_FN(realpath) char *realpath(const char *__p, char *__r) 155 { 156 // PATH_MAX is defined as 4096 157 if (__r && 4096 > __fh_bos(__r, 2)) { 158 char __buf[4096], *__ret; 159 __fh_size_t __l; 160 161 __ret = __orig_realpath(__p, __buf); 162 if (!__ret) 163 return NULL; 164 __l = __builtin_strlen(__ret) + 1; 165 if (__l > __fh_bos(__r, 0)) 166 __builtin_trap(); 167 __builtin_memcpy(__r, __ret, __l); 168 return __r; 169 } 170 return __orig_realpath(__p, __r); 171 } 172 #endif 173 174 #endif // clang 175 176 #ifdef __cplusplus 177 } 178 #endif 179 180 #endif // _FORTIFY_SOURCE 181 182 #endif