Branch data Line data Source code
1 : : /* crypto/mem.c */
2 : : /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 : : * All rights reserved.
4 : : *
5 : : * This package is an SSL implementation written
6 : : * by Eric Young (eay@cryptsoft.com).
7 : : * The implementation was written so as to conform with Netscapes SSL.
8 : : *
9 : : * This library is free for commercial and non-commercial use as long as
10 : : * the following conditions are aheared to. The following conditions
11 : : * apply to all code found in this distribution, be it the RC4, RSA,
12 : : * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 : : * included with this distribution is covered by the same copyright terms
14 : : * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 : : *
16 : : * Copyright remains Eric Young's, and as such any Copyright notices in
17 : : * the code are not to be removed.
18 : : * If this package is used in a product, Eric Young should be given attribution
19 : : * as the author of the parts of the library used.
20 : : * This can be in the form of a textual message at program startup or
21 : : * in documentation (online or textual) provided with the package.
22 : : *
23 : : * Redistribution and use in source and binary forms, with or without
24 : : * modification, are permitted provided that the following conditions
25 : : * are met:
26 : : * 1. Redistributions of source code must retain the copyright
27 : : * notice, this list of conditions and the following disclaimer.
28 : : * 2. Redistributions in binary form must reproduce the above copyright
29 : : * notice, this list of conditions and the following disclaimer in the
30 : : * documentation and/or other materials provided with the distribution.
31 : : * 3. All advertising materials mentioning features or use of this software
32 : : * must display the following acknowledgement:
33 : : * "This product includes cryptographic software written by
34 : : * Eric Young (eay@cryptsoft.com)"
35 : : * The word 'cryptographic' can be left out if the rouines from the library
36 : : * being used are not cryptographic related :-).
37 : : * 4. If you include any Windows specific code (or a derivative thereof) from
38 : : * the apps directory (application code) you must include an acknowledgement:
39 : : * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 : : *
41 : : * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 : : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 : : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 : : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 : : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 : : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 : : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 : : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 : : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 : : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 : : * SUCH DAMAGE.
52 : : *
53 : : * The licence and distribution terms for any publically available version or
54 : : * derivative of this code cannot be changed. i.e. this code cannot simply be
55 : : * copied and put under another distribution licence
56 : : * [including the GNU Public Licence.]
57 : : */
58 : :
59 : : #include <stdio.h>
60 : : #include <stdlib.h>
61 : : #include <openssl/crypto.h>
62 : : #include "cryptlib.h"
63 : :
64 : :
65 : : static int allow_customize = 1; /* we provide flexible functions for */
66 : : static int allow_customize_debug = 1;/* exchanging memory-related functions at
67 : : * run-time, but this must be done
68 : : * before any blocks are actually
69 : : * allocated; or we'll run into huge
70 : : * problems when malloc/free pairs
71 : : * don't match etc. */
72 : :
73 : :
74 : :
75 : : /* the following pointers may be changed as long as 'allow_customize' is set */
76 : :
77 : : static void *(*malloc_func)(size_t) = malloc;
78 : 30014386 : static void *default_malloc_ex(size_t num, const char *file, int line)
79 : 30014386 : { return malloc_func(num); }
80 : : static void *(*malloc_ex_func)(size_t, const char *file, int line)
81 : : = default_malloc_ex;
82 : :
83 : : static void *(*realloc_func)(void *, size_t)= realloc;
84 : 115253 : static void *default_realloc_ex(void *str, size_t num,
85 : : const char *file, int line)
86 : 115253 : { return realloc_func(str,num); }
87 : : static void *(*realloc_ex_func)(void *, size_t, const char *file, int line)
88 : : = default_realloc_ex;
89 : :
90 : : static void (*free_func)(void *) = free;
91 : :
92 : : static void *(*malloc_locked_func)(size_t) = malloc;
93 : 0 : static void *default_malloc_locked_ex(size_t num, const char *file, int line)
94 : 0 : { return malloc_locked_func(num); }
95 : : static void *(*malloc_locked_ex_func)(size_t, const char *file, int line)
96 : : = default_malloc_locked_ex;
97 : :
98 : : static void (*free_locked_func)(void *) = free;
99 : :
100 : :
101 : :
102 : : /* may be changed as long as 'allow_customize_debug' is set */
103 : : /* XXX use correct function pointer types */
104 : : #ifdef CRYPTO_MDEBUG
105 : : /* use default functions from mem_dbg.c */
106 : : static void (*malloc_debug_func)(void *,int,const char *,int,int)
107 : : = CRYPTO_dbg_malloc;
108 : : static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
109 : : = CRYPTO_dbg_realloc;
110 : : static void (*free_debug_func)(void *,int) = CRYPTO_dbg_free;
111 : : static void (*set_debug_options_func)(long) = CRYPTO_dbg_set_options;
112 : : static long (*get_debug_options_func)(void) = CRYPTO_dbg_get_options;
113 : : #else
114 : : /* applications can use CRYPTO_malloc_debug_init() to select above case
115 : : * at run-time */
116 : : static void (*malloc_debug_func)(void *,int,const char *,int,int) = NULL;
117 : : static void (*realloc_debug_func)(void *,void *,int,const char *,int,int)
118 : : = NULL;
119 : : static void (*free_debug_func)(void *,int) = NULL;
120 : : static void (*set_debug_options_func)(long) = NULL;
121 : : static long (*get_debug_options_func)(void) = NULL;
122 : : #endif
123 : :
124 : 725 : int CRYPTO_set_mem_functions(void *(*m)(size_t), void *(*r)(void *, size_t),
125 : : void (*f)(void *))
126 : : {
127 : : /* Dummy call just to ensure OPENSSL_init() gets linked in */
128 : 725 : OPENSSL_init();
129 [ - + ]: 725 : if (!allow_customize)
130 : : return 0;
131 [ # # ][ # # ]: 0 : if ((m == 0) || (r == 0) || (f == 0))
132 : : return 0;
133 : 0 : malloc_func=m; malloc_ex_func=default_malloc_ex;
134 : 0 : realloc_func=r; realloc_ex_func=default_realloc_ex;
135 : 0 : free_func=f;
136 : 0 : malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
137 : 0 : free_locked_func=f;
138 : 0 : return 1;
139 : : }
140 : :
141 : 0 : int CRYPTO_set_mem_ex_functions(
142 : : void *(*m)(size_t,const char *,int),
143 : : void *(*r)(void *, size_t,const char *,int),
144 : : void (*f)(void *))
145 : : {
146 [ # # ]: 0 : if (!allow_customize)
147 : : return 0;
148 [ # # ][ # # ]: 0 : if ((m == 0) || (r == 0) || (f == 0))
149 : : return 0;
150 : 0 : malloc_func=0; malloc_ex_func=m;
151 : 0 : realloc_func=0; realloc_ex_func=r;
152 : 0 : free_func=f;
153 : 0 : malloc_locked_func=0; malloc_locked_ex_func=m;
154 : 0 : free_locked_func=f;
155 : 0 : return 1;
156 : : }
157 : :
158 : 0 : int CRYPTO_set_locked_mem_functions(void *(*m)(size_t), void (*f)(void *))
159 : : {
160 [ # # ]: 0 : if (!allow_customize)
161 : : return 0;
162 [ # # ]: 0 : if ((m == NULL) || (f == NULL))
163 : : return 0;
164 : 0 : malloc_locked_func=m; malloc_locked_ex_func=default_malloc_locked_ex;
165 : 0 : free_locked_func=f;
166 : 0 : return 1;
167 : : }
168 : :
169 : 0 : int CRYPTO_set_locked_mem_ex_functions(
170 : : void *(*m)(size_t,const char *,int),
171 : : void (*f)(void *))
172 : : {
173 [ # # ]: 0 : if (!allow_customize)
174 : : return 0;
175 [ # # ]: 0 : if ((m == NULL) || (f == NULL))
176 : : return 0;
177 : 0 : malloc_locked_func=0; malloc_locked_ex_func=m;
178 : 0 : free_func=f;
179 : 0 : return 1;
180 : : }
181 : :
182 : 1629 : int CRYPTO_set_mem_debug_functions(void (*m)(void *,int,const char *,int,int),
183 : : void (*r)(void *,void *,int,const char *,int,int),
184 : : void (*f)(void *,int),
185 : : void (*so)(long),
186 : : long (*go)(void))
187 : : {
188 [ + - ]: 1629 : if (!allow_customize_debug)
189 : : return 0;
190 : 1629 : malloc_debug_func=m;
191 : 1629 : realloc_debug_func=r;
192 : 1629 : free_debug_func=f;
193 : 1629 : set_debug_options_func=so;
194 : 1629 : get_debug_options_func=go;
195 : 1629 : return 1;
196 : : }
197 : :
198 : :
199 : 0 : void CRYPTO_get_mem_functions(void *(**m)(size_t), void *(**r)(void *, size_t),
200 : : void (**f)(void *))
201 : : {
202 [ # # ]: 0 : if (m != NULL) *m = (malloc_ex_func == default_malloc_ex) ?
203 [ # # ]: 0 : malloc_func : 0;
204 [ # # ]: 0 : if (r != NULL) *r = (realloc_ex_func == default_realloc_ex) ?
205 [ # # ]: 0 : realloc_func : 0;
206 [ # # ]: 0 : if (f != NULL) *f=free_func;
207 : 0 : }
208 : :
209 : 0 : void CRYPTO_get_mem_ex_functions(
210 : : void *(**m)(size_t,const char *,int),
211 : : void *(**r)(void *, size_t,const char *,int),
212 : : void (**f)(void *))
213 : : {
214 [ # # ]: 0 : if (m != NULL) *m = (malloc_ex_func != default_malloc_ex) ?
215 [ # # ]: 0 : malloc_ex_func : 0;
216 [ # # ]: 0 : if (r != NULL) *r = (realloc_ex_func != default_realloc_ex) ?
217 [ # # ]: 0 : realloc_ex_func : 0;
218 [ # # ]: 0 : if (f != NULL) *f=free_func;
219 : 0 : }
220 : :
221 : 0 : void CRYPTO_get_locked_mem_functions(void *(**m)(size_t), void (**f)(void *))
222 : : {
223 [ # # ]: 0 : if (m != NULL) *m = (malloc_locked_ex_func == default_malloc_locked_ex) ?
224 [ # # ]: 0 : malloc_locked_func : 0;
225 [ # # ]: 0 : if (f != NULL) *f=free_locked_func;
226 : 0 : }
227 : :
228 : 0 : void CRYPTO_get_locked_mem_ex_functions(
229 : : void *(**m)(size_t,const char *,int),
230 : : void (**f)(void *))
231 : : {
232 [ # # ]: 0 : if (m != NULL) *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
233 [ # # ]: 0 : malloc_locked_ex_func : 0;
234 [ # # ]: 0 : if (f != NULL) *f=free_locked_func;
235 : 0 : }
236 : :
237 : 0 : void CRYPTO_get_mem_debug_functions(void (**m)(void *,int,const char *,int,int),
238 : : void (**r)(void *,void *,int,const char *,int,int),
239 : : void (**f)(void *,int),
240 : : void (**so)(long),
241 : : long (**go)(void))
242 : : {
243 [ # # ]: 0 : if (m != NULL) *m=malloc_debug_func;
244 [ # # ]: 0 : if (r != NULL) *r=realloc_debug_func;
245 [ # # ]: 0 : if (f != NULL) *f=free_debug_func;
246 [ # # ]: 0 : if (so != NULL) *so=set_debug_options_func;
247 [ # # ]: 0 : if (go != NULL) *go=get_debug_options_func;
248 : 0 : }
249 : :
250 : :
251 : 0 : void *CRYPTO_malloc_locked(int num, const char *file, int line)
252 : : {
253 : 0 : void *ret = NULL;
254 : :
255 [ # # ]: 0 : if (num <= 0) return NULL;
256 : :
257 : 0 : allow_customize = 0;
258 [ # # ]: 0 : if (malloc_debug_func != NULL)
259 : : {
260 : 0 : allow_customize_debug = 0;
261 : 0 : malloc_debug_func(NULL, num, file, line, 0);
262 : : }
263 : 0 : ret = malloc_locked_ex_func(num,file,line);
264 : : #ifdef LEVITTE_DEBUG_MEM
265 : : fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
266 : : #endif
267 [ # # ]: 0 : if (malloc_debug_func != NULL)
268 : 0 : malloc_debug_func(ret, num, file, line, 1);
269 : :
270 : : #ifndef OPENSSL_CPUID_OBJ
271 : : /* Create a dependency on the value of 'cleanse_ctr' so our memory
272 : : * sanitisation function can't be optimised out. NB: We only do
273 : : * this for >2Kb so the overhead doesn't bother us. */
274 : : if(ret && (num > 2048))
275 : : { extern unsigned char cleanse_ctr;
276 : : ((unsigned char *)ret)[0] = cleanse_ctr;
277 : : }
278 : : #endif
279 : :
280 : 0 : return ret;
281 : : }
282 : :
283 : 0 : void CRYPTO_free_locked(void *str)
284 : : {
285 [ # # ]: 0 : if (free_debug_func != NULL)
286 : 0 : free_debug_func(str, 0);
287 : : #ifdef LEVITTE_DEBUG_MEM
288 : : fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
289 : : #endif
290 : 0 : free_locked_func(str);
291 [ # # ]: 0 : if (free_debug_func != NULL)
292 : 0 : free_debug_func(NULL, 1);
293 : 0 : }
294 : :
295 : 30012327 : void *CRYPTO_malloc(int num, const char *file, int line)
296 : : {
297 : 30012327 : void *ret = NULL;
298 : :
299 [ + - ]: 30012327 : if (num <= 0) return NULL;
300 : :
301 : 30012327 : allow_customize = 0;
302 [ + + ]: 30012327 : if (malloc_debug_func != NULL)
303 : : {
304 : 29501481 : allow_customize_debug = 0;
305 : 29501481 : malloc_debug_func(NULL, num, file, line, 0);
306 : : }
307 : 30012327 : ret = malloc_ex_func(num,file,line);
308 : : #ifdef LEVITTE_DEBUG_MEM
309 : : fprintf(stderr, "LEVITTE_DEBUG_MEM: > 0x%p (%d)\n", ret, num);
310 : : #endif
311 [ + + ]: 30012327 : if (malloc_debug_func != NULL)
312 : 29501481 : malloc_debug_func(ret, num, file, line, 1);
313 : :
314 : : #ifndef OPENSSL_CPUID_OBJ
315 : : /* Create a dependency on the value of 'cleanse_ctr' so our memory
316 : : * sanitisation function can't be optimised out. NB: We only do
317 : : * this for >2Kb so the overhead doesn't bother us. */
318 : : if(ret && (num > 2048))
319 : : { extern unsigned char cleanse_ctr;
320 : : ((unsigned char *)ret)[0] = cleanse_ctr;
321 : : }
322 : : #endif
323 : :
324 : 30012327 : return ret;
325 : : }
326 : 0 : char *CRYPTO_strdup(const char *str, const char *file, int line)
327 : : {
328 : 0 : char *ret = CRYPTO_malloc(strlen(str)+1, file, line);
329 : :
330 : : strcpy(ret, str);
331 : 0 : return ret;
332 : : }
333 : :
334 : 115564 : void *CRYPTO_realloc(void *str, int num, const char *file, int line)
335 : : {
336 : 115564 : void *ret = NULL;
337 : :
338 [ + + ]: 115564 : if (str == NULL)
339 : 311 : return CRYPTO_malloc(num, file, line);
340 : :
341 [ + - ]: 115253 : if (num <= 0) return NULL;
342 : :
343 [ + + ]: 115253 : if (realloc_debug_func != NULL)
344 : 115199 : realloc_debug_func(str, NULL, num, file, line, 0);
345 : 115253 : ret = realloc_ex_func(str,num,file,line);
346 : : #ifdef LEVITTE_DEBUG_MEM
347 : : fprintf(stderr, "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n", str, ret, num);
348 : : #endif
349 [ + + ]: 115253 : if (realloc_debug_func != NULL)
350 : 115199 : realloc_debug_func(str, ret, num, file, line, 1);
351 : :
352 : 115253 : return ret;
353 : : }
354 : :
355 : 2059 : void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
356 : : int line)
357 : : {
358 : 2059 : void *ret = NULL;
359 : :
360 [ - + ]: 2059 : if (str == NULL)
361 : 0 : return CRYPTO_malloc(num, file, line);
362 : :
363 [ + - ]: 2059 : if (num <= 0) return NULL;
364 : :
365 : : /* We don't support shrinking the buffer. Note the memcpy that copies
366 : : * |old_len| bytes to the new buffer, below. */
367 [ + - ]: 2059 : if (num < old_len) return NULL;
368 : :
369 [ + - ]: 2059 : if (realloc_debug_func != NULL)
370 : 2059 : realloc_debug_func(str, NULL, num, file, line, 0);
371 : 2059 : ret=malloc_ex_func(num,file,line);
372 [ + - ]: 2059 : if(ret)
373 : : {
374 : 2059 : memcpy(ret,str,old_len);
375 : 2059 : OPENSSL_cleanse(str,old_len);
376 : 2059 : free_func(str);
377 : : }
378 : : #ifdef LEVITTE_DEBUG_MEM
379 : : fprintf(stderr,
380 : : "LEVITTE_DEBUG_MEM: | 0x%p -> 0x%p (%d)\n",
381 : : str, ret, num);
382 : : #endif
383 [ + - ]: 2059 : if (realloc_debug_func != NULL)
384 : 2059 : realloc_debug_func(str, ret, num, file, line, 1);
385 : :
386 : 2059 : return ret;
387 : : }
388 : :
389 : 29982024 : void CRYPTO_free(void *str)
390 : : {
391 [ + + ]: 29982024 : if (free_debug_func != NULL)
392 : 29485374 : free_debug_func(str, 0);
393 : : #ifdef LEVITTE_DEBUG_MEM
394 : : fprintf(stderr, "LEVITTE_DEBUG_MEM: < 0x%p\n", str);
395 : : #endif
396 : 29982024 : free_func(str);
397 [ + + ]: 29982024 : if (free_debug_func != NULL)
398 : 29485374 : free_debug_func(NULL, 1);
399 : 29982024 : }
400 : :
401 : 0 : void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
402 : : {
403 [ # # ]: 0 : if (a != NULL) OPENSSL_free(a);
404 : 0 : a=(char *)OPENSSL_malloc(num);
405 : 0 : return(a);
406 : : }
407 : :
408 : 1623 : void CRYPTO_set_mem_debug_options(long bits)
409 : : {
410 [ + - ]: 1623 : if (set_debug_options_func != NULL)
411 : 1623 : set_debug_options_func(bits);
412 : 1623 : }
413 : :
414 : 0 : long CRYPTO_get_mem_debug_options(void)
415 : : {
416 [ # # ]: 0 : if (get_debug_options_func != NULL)
417 : 0 : return get_debug_options_func();
418 : : return 0;
419 : : }
|