mem.c revision 296465
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
64static int allow_customize = 1; /* we provide flexible functions for */
65static int allow_customize_debug = 1; /* exchanging memory-related functions
66                                       * at run-time, but this must be done
67                                       * before any blocks are actually
68                                       * allocated; or we'll run into huge
69                                       * problems when malloc/free pairs
70                                       * don't match etc. */
71
72/*
73 * the following pointers may be changed as long as 'allow_customize' is set
74 */
75
76static void *(*malloc_func) (size_t) = malloc;
77static void *default_malloc_ex(size_t num, const char *file, int line)
78{
79    return malloc_func(num);
80}
81
82static void *(*malloc_ex_func) (size_t, const char *file, int line)
83    = default_malloc_ex;
84
85static void *(*realloc_func) (void *, size_t) = realloc;
86static void *default_realloc_ex(void *str, size_t num,
87                                const char *file, int line)
88{
89    return realloc_func(str, num);
90}
91
92static void *(*realloc_ex_func) (void *, size_t, const char *file, int line)
93    = default_realloc_ex;
94
95static void (*free_func) (void *) = free;
96
97static void *(*malloc_locked_func) (size_t) = malloc;
98static void *default_malloc_locked_ex(size_t num, const char *file, int line)
99{
100    return malloc_locked_func(num);
101}
102
103static void *(*malloc_locked_ex_func) (size_t, const char *file, int line)
104    = default_malloc_locked_ex;
105
106static void (*free_locked_func) (void *) = free;
107
108/* may be changed as long as 'allow_customize_debug' is set */
109/* XXX use correct function pointer types */
110#if defined(CRYPTO_MDEBUG) && !defined(OPENSSL_FIPS)
111/* use default functions from mem_dbg.c */
112static void (*malloc_debug_func) (void *, int, const char *, int, int)
113    = CRYPTO_dbg_malloc;
114static void (*realloc_debug_func) (void *, void *, int, const char *, int,
115                                   int)
116    = CRYPTO_dbg_realloc;
117static void (*free_debug_func) (void *, int) = CRYPTO_dbg_free;
118static void (*set_debug_options_func) (long) = CRYPTO_dbg_set_options;
119static long (*get_debug_options_func) (void) = CRYPTO_dbg_get_options;
120
121static int (*push_info_func) (const char *info, const char *file, int line)
122    = CRYPTO_dbg_push_info;
123static int (*pop_info_func) (void)
124    = CRYPTO_dbg_pop_info;
125static int (*remove_all_info_func) (void)
126    = CRYPTO_dbg_remove_all_info;
127
128#else
129/*
130 * applications can use CRYPTO_malloc_debug_init() to select above case at
131 * run-time
132 */
133static void (*malloc_debug_func) (void *, int, const char *, int, int) = NULL;
134static void (*realloc_debug_func) (void *, void *, int, const char *, int,
135                                   int)
136    = NULL;
137static void (*free_debug_func) (void *, int) = NULL;
138static void (*set_debug_options_func) (long) = NULL;
139static long (*get_debug_options_func) (void) = NULL;
140
141static int (*push_info_func) (const char *info, const char *file, int line)
142    = NULL;
143static int (*pop_info_func) (void) = NULL;
144static int (*remove_all_info_func) (void) = NULL;
145
146#endif
147
148int CRYPTO_set_mem_functions(void *(*m) (size_t), void *(*r) (void *, size_t),
149                             void (*f) (void *))
150{
151    if (!allow_customize)
152        return 0;
153    if ((m == 0) || (r == 0) || (f == 0))
154        return 0;
155    malloc_func = m;
156    malloc_ex_func = default_malloc_ex;
157    realloc_func = r;
158    realloc_ex_func = default_realloc_ex;
159    free_func = f;
160    malloc_locked_func = m;
161    malloc_locked_ex_func = default_malloc_locked_ex;
162    free_locked_func = f;
163    return 1;
164}
165
166int CRYPTO_set_mem_ex_functions(void *(*m) (size_t, const char *, int),
167                                void *(*r) (void *, size_t, const char *,
168                                            int), void (*f) (void *))
169{
170    if (!allow_customize)
171        return 0;
172    if ((m == 0) || (r == 0) || (f == 0))
173        return 0;
174    malloc_func = 0;
175    malloc_ex_func = m;
176    realloc_func = 0;
177    realloc_ex_func = r;
178    free_func = f;
179    malloc_locked_func = 0;
180    malloc_locked_ex_func = m;
181    free_locked_func = f;
182    return 1;
183}
184
185int CRYPTO_set_locked_mem_functions(void *(*m) (size_t), void (*f) (void *))
186{
187    if (!allow_customize)
188        return 0;
189    if ((m == NULL) || (f == NULL))
190        return 0;
191    malloc_locked_func = m;
192    malloc_locked_ex_func = default_malloc_locked_ex;
193    free_locked_func = f;
194    return 1;
195}
196
197int CRYPTO_set_locked_mem_ex_functions(void *(*m) (size_t, const char *, int),
198                                       void (*f) (void *))
199{
200    if (!allow_customize)
201        return 0;
202    if ((m == NULL) || (f == NULL))
203        return 0;
204    malloc_locked_func = 0;
205    malloc_locked_ex_func = m;
206    free_func = f;
207    return 1;
208}
209
210int CRYPTO_set_mem_debug_functions(void (*m)
211                                    (void *, int, const char *, int, int),
212                                   void (*r) (void *, void *, int,
213                                              const char *, int, int),
214                                   void (*f) (void *, int), void (*so) (long),
215                                   long (*go) (void))
216{
217    if (!allow_customize_debug)
218        return 0;
219    malloc_debug_func = m;
220    realloc_debug_func = r;
221    free_debug_func = f;
222    set_debug_options_func = so;
223    get_debug_options_func = go;
224    return 1;
225}
226
227void CRYPTO_set_mem_info_functions(int (*push_info_fn)
228                                    (const char *info, const char *file,
229                                     int line), int (*pop_info_fn) (void),
230                                   int (*remove_all_info_fn) (void))
231{
232    push_info_func = push_info_fn;
233    pop_info_func = pop_info_fn;
234    remove_all_info_func = remove_all_info_fn;
235}
236
237void CRYPTO_get_mem_functions(void *(**m) (size_t),
238                              void *(**r) (void *, size_t),
239                              void (**f) (void *))
240{
241    if (m != NULL)
242        *m = (malloc_ex_func == default_malloc_ex) ? malloc_func : 0;
243    if (r != NULL)
244        *r = (realloc_ex_func == default_realloc_ex) ? realloc_func : 0;
245    if (f != NULL)
246        *f = free_func;
247}
248
249void CRYPTO_get_mem_ex_functions(void *(**m) (size_t, const char *, int),
250                                 void *(**r) (void *, size_t, const char *,
251                                              int), void (**f) (void *))
252{
253    if (m != NULL)
254        *m = (malloc_ex_func != default_malloc_ex) ? malloc_ex_func : 0;
255    if (r != NULL)
256        *r = (realloc_ex_func != default_realloc_ex) ? realloc_ex_func : 0;
257    if (f != NULL)
258        *f = free_func;
259}
260
261void CRYPTO_get_locked_mem_functions(void *(**m) (size_t),
262                                     void (**f) (void *))
263{
264    if (m != NULL)
265        *m = (malloc_locked_ex_func == default_malloc_locked_ex) ?
266            malloc_locked_func : 0;
267    if (f != NULL)
268        *f = free_locked_func;
269}
270
271void CRYPTO_get_locked_mem_ex_functions(void
272                                        *(**m) (size_t, const char *, int),
273                                        void (**f) (void *))
274{
275    if (m != NULL)
276        *m = (malloc_locked_ex_func != default_malloc_locked_ex) ?
277            malloc_locked_ex_func : 0;
278    if (f != NULL)
279        *f = free_locked_func;
280}
281
282void CRYPTO_get_mem_debug_functions(void (**m)
283                                     (void *, int, const char *, int, int),
284                                    void (**r) (void *, void *, int,
285                                                const char *, int, int),
286                                    void (**f) (void *, int),
287                                    void (**so) (long), long (**go) (void))
288{
289    if (m != NULL)
290        *m = malloc_debug_func;
291    if (r != NULL)
292        *r = realloc_debug_func;
293    if (f != NULL)
294        *f = free_debug_func;
295    if (so != NULL)
296        *so = set_debug_options_func;
297    if (go != NULL)
298        *go = get_debug_options_func;
299}
300
301void *CRYPTO_malloc_locked(int num, const char *file, int line)
302{
303    void *ret = NULL;
304    extern unsigned char cleanse_ctr;
305
306    if (num <= 0)
307        return NULL;
308
309    allow_customize = 0;
310    if (malloc_debug_func != NULL) {
311        allow_customize_debug = 0;
312        malloc_debug_func(NULL, num, file, line, 0);
313    }
314    ret = malloc_locked_ex_func(num, file, line);
315#ifdef LEVITTE_DEBUG_MEM
316    fprintf(stderr, "LEVITTE_DEBUG_MEM:         > 0x%p (%d)\n", ret, num);
317#endif
318    if (malloc_debug_func != NULL)
319        malloc_debug_func(ret, num, file, line, 1);
320
321    /*
322     * Create a dependency on the value of 'cleanse_ctr' so our memory
323     * sanitisation function can't be optimised out. NB: We only do this for
324     * >2Kb so the overhead doesn't bother us.
325     */
326    if (ret && (num > 2048))
327        ((unsigned char *)ret)[0] = cleanse_ctr;
328
329    return ret;
330}
331
332void CRYPTO_free_locked(void *str)
333{
334    if (free_debug_func != NULL)
335        free_debug_func(str, 0);
336#ifdef LEVITTE_DEBUG_MEM
337    fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
338#endif
339    free_locked_func(str);
340    if (free_debug_func != NULL)
341        free_debug_func(NULL, 1);
342}
343
344void *CRYPTO_malloc(int num, const char *file, int line)
345{
346    void *ret = NULL;
347    extern unsigned char cleanse_ctr;
348
349    if (num <= 0)
350        return NULL;
351
352    allow_customize = 0;
353    if (malloc_debug_func != NULL) {
354        allow_customize_debug = 0;
355        malloc_debug_func(NULL, num, file, line, 0);
356    }
357    ret = malloc_ex_func(num, file, line);
358#ifdef LEVITTE_DEBUG_MEM
359    fprintf(stderr, "LEVITTE_DEBUG_MEM:         > 0x%p (%d)\n", ret, num);
360#endif
361    if (malloc_debug_func != NULL)
362        malloc_debug_func(ret, num, file, line, 1);
363
364    /*
365     * Create a dependency on the value of 'cleanse_ctr' so our memory
366     * sanitisation function can't be optimised out. NB: We only do this for
367     * >2Kb so the overhead doesn't bother us.
368     */
369    if (ret && (num > 2048))
370        ((unsigned char *)ret)[0] = cleanse_ctr;
371
372    return ret;
373}
374
375void *CRYPTO_realloc(void *str, int num, const char *file, int line)
376{
377    void *ret = NULL;
378
379    if (str == NULL)
380        return CRYPTO_malloc(num, file, line);
381
382    if (num <= 0)
383        return NULL;
384
385    if (realloc_debug_func != NULL)
386        realloc_debug_func(str, NULL, num, file, line, 0);
387    ret = realloc_ex_func(str, num, file, line);
388#ifdef LEVITTE_DEBUG_MEM
389    fprintf(stderr, "LEVITTE_DEBUG_MEM:         | 0x%p -> 0x%p (%d)\n", str,
390            ret, num);
391#endif
392    if (realloc_debug_func != NULL)
393        realloc_debug_func(str, ret, num, file, line, 1);
394
395    return ret;
396}
397
398void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
399                           int line)
400{
401    void *ret = NULL;
402
403    if (str == NULL)
404        return CRYPTO_malloc(num, file, line);
405
406    if (num <= 0)
407        return NULL;
408
409    /*
410     * We don't support shrinking the buffer. Note the memcpy that copies
411     * |old_len| bytes to the new buffer, below.
412     */
413    if (num < old_len)
414        return NULL;
415
416    if (realloc_debug_func != NULL)
417        realloc_debug_func(str, NULL, num, file, line, 0);
418    ret = malloc_ex_func(num, file, line);
419    if (ret) {
420        memcpy(ret, str, old_len);
421        OPENSSL_cleanse(str, old_len);
422        free_func(str);
423    }
424#ifdef LEVITTE_DEBUG_MEM
425    fprintf(stderr,
426            "LEVITTE_DEBUG_MEM:         | 0x%p -> 0x%p (%d)\n",
427            str, ret, num);
428#endif
429    if (realloc_debug_func != NULL)
430        realloc_debug_func(str, ret, num, file, line, 1);
431
432    return ret;
433}
434
435void CRYPTO_free(void *str)
436{
437    if (free_debug_func != NULL)
438        free_debug_func(str, 0);
439#ifdef LEVITTE_DEBUG_MEM
440    fprintf(stderr, "LEVITTE_DEBUG_MEM:         < 0x%p\n", str);
441#endif
442    free_func(str);
443    if (free_debug_func != NULL)
444        free_debug_func(NULL, 1);
445}
446
447void *CRYPTO_remalloc(void *a, int num, const char *file, int line)
448{
449    if (a != NULL)
450        OPENSSL_free(a);
451    a = (char *)OPENSSL_malloc(num);
452    return (a);
453}
454
455void CRYPTO_set_mem_debug_options(long bits)
456{
457    if (set_debug_options_func != NULL)
458        set_debug_options_func(bits);
459}
460
461long CRYPTO_get_mem_debug_options(void)
462{
463    if (get_debug_options_func != NULL)
464        return get_debug_options_func();
465    return 0;
466}
467
468int CRYPTO_push_info_(const char *info, const char *file, int line)
469{
470    if (push_info_func)
471        return push_info_func(info, file, line);
472    return 1;
473}
474
475int CRYPTO_pop_info(void)
476{
477    if (pop_info_func)
478        return pop_info_func();
479    return 1;
480}
481
482int CRYPTO_remove_all_info(void)
483{
484    if (remove_all_info_func)
485        return remove_all_info_func();
486    return 1;
487}
488