Line data Source code
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 1 : if (__ws && __wn > __b / sizeof(wchar_t))
43 2 : __builtin_trap();
44 2 : 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 1 : if (nmemb * size> __b)
93 2 : __builtin_trap();
94 :
95 2 : 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
|