/src/flac/include/share/alloc.h
Line | Count | Source (jump to first uncovered line) |
1 | | /* alloc - Convenience routines for safely allocating memory |
2 | | * Copyright (C) 2007-2009 Josh Coalson |
3 | | * Copyright (C) 2011-2023 Xiph.Org Foundation |
4 | | * |
5 | | * Redistribution and use in source and binary forms, with or without |
6 | | * modification, are permitted provided that the following conditions |
7 | | * are met: |
8 | | * |
9 | | * - Redistributions of source code must retain the above copyright |
10 | | * notice, this list of conditions and the following disclaimer. |
11 | | * |
12 | | * - Redistributions in binary form must reproduce the above copyright |
13 | | * notice, this list of conditions and the following disclaimer in the |
14 | | * documentation and/or other materials provided with the distribution. |
15 | | * |
16 | | * - Neither the name of the Xiph.org Foundation nor the names of its |
17 | | * contributors may be used to endorse or promote products derived from |
18 | | * this software without specific prior written permission. |
19 | | * |
20 | | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
21 | | * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
22 | | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
23 | | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR |
24 | | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
25 | | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
26 | | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
27 | | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF |
28 | | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING |
29 | | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS |
30 | | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
31 | | */ |
32 | | |
33 | | #ifndef FLAC__SHARE__ALLOC_H |
34 | | #define FLAC__SHARE__ALLOC_H |
35 | | |
36 | | #ifdef HAVE_CONFIG_H |
37 | | # include <config.h> |
38 | | #endif |
39 | | |
40 | | /* WATCHOUT: for c++ you may have to #define __STDC_LIMIT_MACROS 1 real early |
41 | | * before #including this file, otherwise SIZE_MAX might not be defined |
42 | | */ |
43 | | |
44 | | #include <limits.h> /* for SIZE_MAX */ |
45 | | #ifdef HAVE_STDINT_H |
46 | | #include <stdint.h> /* for SIZE_MAX in case limits.h didn't get it */ |
47 | | #endif |
48 | | #include <stdlib.h> /* for size_t, malloc(), etc */ |
49 | | #include "share/compat.h" |
50 | | |
51 | | #ifndef SIZE_MAX |
52 | | # ifndef SIZE_T_MAX |
53 | | # ifdef _MSC_VER |
54 | | # ifdef _WIN64 |
55 | | # define SIZE_T_MAX FLAC__U64L(0xffffffffffffffff) |
56 | | # else |
57 | | # define SIZE_T_MAX 0xffffffff |
58 | | # endif |
59 | | # else |
60 | | # error |
61 | | # endif |
62 | | # endif |
63 | | # define SIZE_MAX SIZE_T_MAX |
64 | | #endif |
65 | | |
66 | | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
67 | | extern int alloc_check_threshold, alloc_check_counter; |
68 | | |
69 | 10.3k | static inline int alloc_check() { |
70 | 10.3k | if(alloc_check_threshold == INT32_MAX) |
71 | 10.3k | return 0; |
72 | 0 | else if(alloc_check_counter++ == alloc_check_threshold) |
73 | 0 | return 1; |
74 | 0 | else |
75 | 0 | return 0; |
76 | 10.3k | } Unexecuted instantiation: utf8.c:alloc_check Line | Count | Source | 69 | 1.42k | static inline int alloc_check() { | 70 | 1.42k | if(alloc_check_threshold == INT32_MAX) | 71 | 1.42k | return 0; | 72 | 0 | else if(alloc_check_counter++ == alloc_check_threshold) | 73 | 0 | return 1; | 74 | 0 | else | 75 | 0 | return 0; | 76 | 1.42k | } |
Line | Count | Source | 69 | 3.25k | static inline int alloc_check() { | 70 | 3.25k | if(alloc_check_threshold == INT32_MAX) | 71 | 3.25k | return 0; | 72 | 0 | else if(alloc_check_counter++ == alloc_check_threshold) | 73 | 0 | return 1; | 74 | 0 | else | 75 | 0 | return 0; | 76 | 3.25k | } |
replaygain_analysis.c:alloc_check Line | Count | Source | 69 | 5.65k | static inline int alloc_check() { | 70 | 5.65k | if(alloc_check_threshold == INT32_MAX) | 71 | 5.65k | return 0; | 72 | 0 | else if(alloc_check_counter++ == alloc_check_threshold) | 73 | 0 | return 1; | 74 | 0 | else | 75 | 0 | return 0; | 76 | 5.65k | } |
|
77 | | |
78 | | #endif |
79 | | |
80 | | /* avoid malloc()ing 0 bytes, see: |
81 | | * https://www.securecoding.cert.org/confluence/display/seccode/MEM04-A.+Do+not+make+assumptions+about+the+result+of+allocating+0+bytes?focusedCommentId=5407003 |
82 | | */ |
83 | | |
84 | | static inline void *safe_malloc_(size_t size) |
85 | 3.25k | { |
86 | 3.25k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
87 | | /* Fail if requested */ |
88 | 3.25k | if(alloc_check()) |
89 | 0 | return NULL; |
90 | 3.25k | #endif |
91 | | /* malloc(0) is undefined; FLAC src convention is to always allocate */ |
92 | 3.25k | if(!size) |
93 | 0 | size++; |
94 | 3.25k | return malloc(size); |
95 | 3.25k | } Unexecuted instantiation: utf8.c:safe_malloc_ Unexecuted instantiation: iconvert.c:safe_malloc_ Line | Count | Source | 85 | 3.25k | { | 86 | 3.25k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 87 | | /* Fail if requested */ | 88 | 3.25k | if(alloc_check()) | 89 | 0 | return NULL; | 90 | 3.25k | #endif | 91 | | /* malloc(0) is undefined; FLAC src convention is to always allocate */ | 92 | 3.25k | if(!size) | 93 | 0 | size++; | 94 | 3.25k | return malloc(size); | 95 | 3.25k | } |
Unexecuted instantiation: replaygain_analysis.c:safe_malloc_ |
96 | | |
97 | | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
98 | | static inline void *malloc_(size_t size) |
99 | 0 | { |
100 | 0 | /* Fail if requested */ |
101 | 0 | if(alloc_check()) |
102 | 0 | return NULL; |
103 | 0 | return malloc(size); |
104 | 0 | } Unexecuted instantiation: utf8.c:malloc_ Unexecuted instantiation: iconvert.c:malloc_ Unexecuted instantiation: picture.c:malloc_ Unexecuted instantiation: replaygain_analysis.c:malloc_ |
105 | | #else |
106 | | #define malloc_ malloc |
107 | | #endif |
108 | | |
109 | | |
110 | | |
111 | | static inline void *safe_calloc_(size_t nmemb, size_t size) |
112 | 0 | { |
113 | 0 | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
114 | 0 | /* Fail if requested */ |
115 | 0 | if(alloc_check()) |
116 | 0 | return NULL; |
117 | 0 | #endif |
118 | 0 | if(!nmemb || !size) |
119 | 0 | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ |
120 | 0 | return calloc(nmemb, size); |
121 | 0 | } Unexecuted instantiation: utf8.c:safe_calloc_ Unexecuted instantiation: iconvert.c:safe_calloc_ Unexecuted instantiation: picture.c:safe_calloc_ Unexecuted instantiation: replaygain_analysis.c:safe_calloc_ |
122 | | |
123 | | /*@@@@ there's probably a better way to prevent overflows when allocating untrusted sums but this works for now */ |
124 | | |
125 | | static inline void *safe_malloc_add_2op_(size_t size1, size_t size2) |
126 | 2.91k | { |
127 | 2.91k | size2 += size1; |
128 | 2.91k | if(size2 < size1) |
129 | 0 | return 0; |
130 | 2.91k | return safe_malloc_(size2); |
131 | 2.91k | } Unexecuted instantiation: utf8.c:safe_malloc_add_2op_ Unexecuted instantiation: iconvert.c:safe_malloc_add_2op_ picture.c:safe_malloc_add_2op_ Line | Count | Source | 126 | 2.91k | { | 127 | 2.91k | size2 += size1; | 128 | 2.91k | if(size2 < size1) | 129 | 0 | return 0; | 130 | 2.91k | return safe_malloc_(size2); | 131 | 2.91k | } |
Unexecuted instantiation: replaygain_analysis.c:safe_malloc_add_2op_ |
132 | | |
133 | | static inline void *safe_malloc_add_3op_(size_t size1, size_t size2, size_t size3) |
134 | 0 | { |
135 | 0 | size2 += size1; |
136 | 0 | if(size2 < size1) |
137 | 0 | return 0; |
138 | 0 | size3 += size2; |
139 | 0 | if(size3 < size2) |
140 | 0 | return 0; |
141 | 0 | return safe_malloc_(size3); |
142 | 0 | } Unexecuted instantiation: utf8.c:safe_malloc_add_3op_ Unexecuted instantiation: iconvert.c:safe_malloc_add_3op_ Unexecuted instantiation: picture.c:safe_malloc_add_3op_ Unexecuted instantiation: replaygain_analysis.c:safe_malloc_add_3op_ |
143 | | |
144 | | static inline void *safe_malloc_add_4op_(size_t size1, size_t size2, size_t size3, size_t size4) |
145 | 0 | { |
146 | 0 | size2 += size1; |
147 | 0 | if(size2 < size1) |
148 | 0 | return 0; |
149 | 0 | size3 += size2; |
150 | 0 | if(size3 < size2) |
151 | 0 | return 0; |
152 | 0 | size4 += size3; |
153 | 0 | if(size4 < size3) |
154 | 0 | return 0; |
155 | 0 | return safe_malloc_(size4); |
156 | 0 | } Unexecuted instantiation: utf8.c:safe_malloc_add_4op_ Unexecuted instantiation: iconvert.c:safe_malloc_add_4op_ Unexecuted instantiation: picture.c:safe_malloc_add_4op_ Unexecuted instantiation: replaygain_analysis.c:safe_malloc_add_4op_ |
157 | | |
158 | | void *safe_malloc_mul_2op_(size_t size1, size_t size2) ; |
159 | | |
160 | | static inline void *safe_malloc_mul_3op_(size_t size1, size_t size2, size_t size3) |
161 | 0 | { |
162 | 0 | if(!size1 || !size2 || !size3) |
163 | 0 | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ |
164 | 0 | if(size1 > SIZE_MAX / size2) |
165 | 0 | return 0; |
166 | 0 | size1 *= size2; |
167 | 0 | if(size1 > SIZE_MAX / size3) |
168 | 0 | return 0; |
169 | 0 | return malloc_(size1*size3); |
170 | 0 | } Unexecuted instantiation: utf8.c:safe_malloc_mul_3op_ Unexecuted instantiation: iconvert.c:safe_malloc_mul_3op_ Unexecuted instantiation: picture.c:safe_malloc_mul_3op_ Unexecuted instantiation: replaygain_analysis.c:safe_malloc_mul_3op_ |
171 | | |
172 | | /* size1*size2 + size3 */ |
173 | | static inline void *safe_malloc_mul2add_(size_t size1, size_t size2, size_t size3) |
174 | 0 | { |
175 | 0 | if(!size1 || !size2) |
176 | 0 | return safe_malloc_(size3); |
177 | 0 | if(size1 > SIZE_MAX / size2) |
178 | 0 | return 0; |
179 | 0 | return safe_malloc_add_2op_(size1*size2, size3); |
180 | 0 | } Unexecuted instantiation: utf8.c:safe_malloc_mul2add_ Unexecuted instantiation: iconvert.c:safe_malloc_mul2add_ Unexecuted instantiation: picture.c:safe_malloc_mul2add_ Unexecuted instantiation: replaygain_analysis.c:safe_malloc_mul2add_ |
181 | | |
182 | | /* size1 * (size2 + size3) */ |
183 | | static inline void *safe_malloc_muladd2_(size_t size1, size_t size2, size_t size3) |
184 | 0 | { |
185 | 0 | if(!size1 || (!size2 && !size3)) |
186 | 0 | return malloc(1); /* malloc(0) is undefined; FLAC src convention is to always allocate */ |
187 | 0 | size2 += size3; |
188 | 0 | if(size2 < size3) |
189 | 0 | return 0; |
190 | 0 | if(size1 > SIZE_MAX / size2) |
191 | 0 | return 0; |
192 | 0 | return malloc_(size1*size2); |
193 | 0 | } Unexecuted instantiation: utf8.c:safe_malloc_muladd2_ Unexecuted instantiation: iconvert.c:safe_malloc_muladd2_ Unexecuted instantiation: picture.c:safe_malloc_muladd2_ Unexecuted instantiation: replaygain_analysis.c:safe_malloc_muladd2_ |
194 | | |
195 | | static inline void *safe_realloc_(void *ptr, size_t size) |
196 | 5.65k | { |
197 | 5.65k | void *oldptr; |
198 | 5.65k | void *newptr; |
199 | 5.65k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
200 | | /* Fail if requested */ |
201 | 5.65k | if(alloc_check() && size > 0) { |
202 | 0 | free(ptr); |
203 | 0 | return NULL; |
204 | 0 | } |
205 | 5.65k | #endif |
206 | 5.65k | oldptr = ptr; |
207 | 5.65k | newptr = realloc(ptr, size); |
208 | 5.65k | if(size > 0 && newptr == 0) |
209 | 0 | free(oldptr); |
210 | 5.65k | return newptr; |
211 | 5.65k | } Unexecuted instantiation: utf8.c:safe_realloc_ Unexecuted instantiation: iconvert.c:safe_realloc_ Unexecuted instantiation: picture.c:safe_realloc_ replaygain_analysis.c:safe_realloc_ Line | Count | Source | 196 | 5.65k | { | 197 | 5.65k | void *oldptr; | 198 | 5.65k | void *newptr; | 199 | 5.65k | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION | 200 | | /* Fail if requested */ | 201 | 5.65k | if(alloc_check() && size > 0) { | 202 | 0 | free(ptr); | 203 | 0 | return NULL; | 204 | 0 | } | 205 | 5.65k | #endif | 206 | 5.65k | oldptr = ptr; | 207 | 5.65k | newptr = realloc(ptr, size); | 208 | 5.65k | if(size > 0 && newptr == 0) | 209 | 0 | free(oldptr); | 210 | 5.65k | return newptr; | 211 | 5.65k | } |
|
212 | | |
213 | | #ifdef FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION |
214 | | static inline void *realloc_(void *ptr, size_t size) |
215 | 1.42k | { |
216 | | /* Fail if requested */ |
217 | 1.42k | if(alloc_check()) |
218 | 0 | return NULL; |
219 | 1.42k | return realloc(ptr, size); |
220 | 1.42k | } Unexecuted instantiation: utf8.c:realloc_ Line | Count | Source | 215 | 1.42k | { | 216 | | /* Fail if requested */ | 217 | 1.42k | if(alloc_check()) | 218 | 0 | return NULL; | 219 | 1.42k | return realloc(ptr, size); | 220 | 1.42k | } |
Unexecuted instantiation: picture.c:realloc_ Unexecuted instantiation: replaygain_analysis.c:realloc_ |
221 | | #else |
222 | | #define realloc_ realloc |
223 | | #endif |
224 | | |
225 | | |
226 | | static inline void *safe_realloc_nofree_add_2op_(void *ptr, size_t size1, size_t size2) |
227 | 1.42k | { |
228 | 1.42k | size2 += size1; |
229 | 1.42k | if(size2 < size1) |
230 | 0 | return 0; |
231 | 1.42k | return realloc_(ptr, size2); |
232 | 1.42k | } Unexecuted instantiation: utf8.c:safe_realloc_nofree_add_2op_ iconvert.c:safe_realloc_nofree_add_2op_ Line | Count | Source | 227 | 1.42k | { | 228 | 1.42k | size2 += size1; | 229 | 1.42k | if(size2 < size1) | 230 | 0 | return 0; | 231 | 1.42k | return realloc_(ptr, size2); | 232 | 1.42k | } |
Unexecuted instantiation: picture.c:safe_realloc_nofree_add_2op_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_nofree_add_2op_ |
233 | | |
234 | | static inline void *safe_realloc_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) |
235 | 0 | { |
236 | 0 | size2 += size1; |
237 | 0 | if(size2 < size1) { |
238 | 0 | free(ptr); |
239 | 0 | return 0; |
240 | 0 | } |
241 | 0 | size3 += size2; |
242 | 0 | if(size3 < size2) { |
243 | 0 | free(ptr); |
244 | 0 | return 0; |
245 | 0 | } |
246 | 0 | return safe_realloc_(ptr, size3); |
247 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_add_3op_ Unexecuted instantiation: iconvert.c:safe_realloc_add_3op_ Unexecuted instantiation: picture.c:safe_realloc_add_3op_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_add_3op_ |
248 | | |
249 | | static inline void *safe_realloc_nofree_add_3op_(void *ptr, size_t size1, size_t size2, size_t size3) |
250 | 0 | { |
251 | 0 | size2 += size1; |
252 | 0 | if(size2 < size1) |
253 | 0 | return 0; |
254 | 0 | size3 += size2; |
255 | 0 | if(size3 < size2) |
256 | 0 | return 0; |
257 | 0 | return realloc_(ptr, size3); |
258 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_nofree_add_3op_ Unexecuted instantiation: iconvert.c:safe_realloc_nofree_add_3op_ Unexecuted instantiation: picture.c:safe_realloc_nofree_add_3op_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_nofree_add_3op_ |
259 | | |
260 | | static inline void *safe_realloc_nofree_add_4op_(void *ptr, size_t size1, size_t size2, size_t size3, size_t size4) |
261 | 0 | { |
262 | 0 | size2 += size1; |
263 | 0 | if(size2 < size1) |
264 | 0 | return 0; |
265 | 0 | size3 += size2; |
266 | 0 | if(size3 < size2) |
267 | 0 | return 0; |
268 | 0 | size4 += size3; |
269 | 0 | if(size4 < size3) |
270 | 0 | return 0; |
271 | 0 | return realloc_(ptr, size4); |
272 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_nofree_add_4op_ Unexecuted instantiation: iconvert.c:safe_realloc_nofree_add_4op_ Unexecuted instantiation: picture.c:safe_realloc_nofree_add_4op_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_nofree_add_4op_ |
273 | | |
274 | | static inline void *safe_realloc_mul_2op_(void *ptr, size_t size1, size_t size2) |
275 | 0 | { |
276 | 0 | if(!size1 || !size2) |
277 | 0 | return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ |
278 | 0 | if(size1 > SIZE_MAX / size2) { |
279 | 0 | free(ptr); |
280 | 0 | return 0; |
281 | 0 | } |
282 | 0 | return safe_realloc_(ptr, size1*size2); |
283 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_mul_2op_ Unexecuted instantiation: iconvert.c:safe_realloc_mul_2op_ Unexecuted instantiation: picture.c:safe_realloc_mul_2op_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_mul_2op_ |
284 | | |
285 | | static inline void *safe_realloc_nofree_mul_2op_(void *ptr, size_t size1, size_t size2) |
286 | 0 | { |
287 | 0 | if(!size1 || !size2) |
288 | 0 | return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ |
289 | 0 | if(size1 > SIZE_MAX / size2) |
290 | 0 | return 0; |
291 | 0 | return realloc_(ptr, size1*size2); |
292 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_nofree_mul_2op_ Unexecuted instantiation: iconvert.c:safe_realloc_nofree_mul_2op_ Unexecuted instantiation: picture.c:safe_realloc_nofree_mul_2op_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_nofree_mul_2op_ |
293 | | |
294 | | /* size1 * (size2 + size3) */ |
295 | | static inline void *safe_realloc_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) |
296 | 0 | { |
297 | 0 | if(!size1 || (!size2 && !size3)) |
298 | 0 | return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ |
299 | 0 | size2 += size3; |
300 | 0 | if(size2 < size3) { |
301 | 0 | free(ptr); |
302 | 0 | return 0; |
303 | 0 | } |
304 | 0 | return safe_realloc_mul_2op_(ptr, size1, size2); |
305 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_muladd2_ Unexecuted instantiation: iconvert.c:safe_realloc_muladd2_ Unexecuted instantiation: picture.c:safe_realloc_muladd2_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_muladd2_ |
306 | | |
307 | | /* size1 * (size2 + size3) */ |
308 | | static inline void *safe_realloc_nofree_muladd2_(void *ptr, size_t size1, size_t size2, size_t size3) |
309 | 0 | { |
310 | 0 | if(!size1 || (!size2 && !size3)) |
311 | 0 | return realloc(ptr, 0); /* preserve POSIX realloc(ptr, 0) semantics */ |
312 | 0 | size2 += size3; |
313 | 0 | if(size2 < size3) |
314 | 0 | return 0; |
315 | 0 | return safe_realloc_nofree_mul_2op_(ptr, size1, size2); |
316 | 0 | } Unexecuted instantiation: utf8.c:safe_realloc_nofree_muladd2_ Unexecuted instantiation: iconvert.c:safe_realloc_nofree_muladd2_ Unexecuted instantiation: picture.c:safe_realloc_nofree_muladd2_ Unexecuted instantiation: replaygain_analysis.c:safe_realloc_nofree_muladd2_ |
317 | | |
318 | | #endif |