mem.c 4.4 KB
Newer Older
R
Rich Salz 已提交
1 2
/*
 * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3
 *
R
Rich Salz 已提交
4 5 6 7
 * Licensed under the OpenSSL license (the "License").  You may not use
 * this file except in compliance with the License.  You can obtain a copy
 * in the file LICENSE in the source distribution or at
 * https://www.openssl.org/source/license.html
8 9 10 11
 */

#include <stdio.h>
#include <stdlib.h>
R
Rich Salz 已提交
12
#include <limits.h>
13
#include <openssl/crypto.h>
14
#include "internal/cryptlib.h"
15

16 17 18
/*
 * the following pointers may be changed as long as 'allow_customize' is set
 */
R
Rich Salz 已提交
19
static int allow_customize = 1;
20

21
static void *(*malloc_impl)(size_t, const char *, int)
R
Rich Salz 已提交
22
    = CRYPTO_malloc;
23
static void *(*realloc_impl)(void *, size_t, const char *, int)
R
Rich Salz 已提交
24
    = CRYPTO_realloc;
25
static void (*free_impl)(void *, const char *, int)
R
Rich Salz 已提交
26
    = CRYPTO_free;
R
Rich Salz 已提交
27

28
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
R
Rich Salz 已提交
29
static int call_malloc_debug = 1;
30
#else
R
Rich Salz 已提交
31
static int call_malloc_debug = 0;
32
#endif
33

R
Rich Salz 已提交
34 35 36
int CRYPTO_set_mem_functions(
        void *(*m)(size_t, const char *, int),
        void *(*r)(void *, size_t, const char *, int),
37
        void (*f)(void *, const char *, int))
R
Rich Salz 已提交
38 39 40
{
    if (!allow_customize)
        return 0;
R
Rich Salz 已提交
41
    if (m)
42
        malloc_impl = m;
R
Rich Salz 已提交
43
    if (r)
44
        realloc_impl = r;
R
Rich Salz 已提交
45
    if (f)
46
        free_impl = f;
R
Rich Salz 已提交
47 48 49
    return 1;
}

R
Rich Salz 已提交
50
int CRYPTO_set_mem_debug(int flag)
R
Rich Salz 已提交
51 52 53
{
    if (!allow_customize)
        return 0;
R
Rich Salz 已提交
54
    call_malloc_debug = flag;
55 56 57
    return 1;
}

R
Rich Salz 已提交
58 59 60
void CRYPTO_get_mem_functions(
        void *(**m)(size_t, const char *, int),
        void *(**r)(void *, size_t, const char *, int),
61
        void (**f)(void *, const char *, int))
62 63
{
    if (m != NULL)
64
        *m = malloc_impl;
65
    if (r != NULL)
66
        *r = realloc_impl;
R
Rich Salz 已提交
67
    if (f != NULL)
68
        *f = free_impl;
69
}
70

71
void *CRYPTO_malloc(size_t num, const char *file, int line)
72 73 74
{
    void *ret = NULL;

75 76 77
    if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
        return malloc_impl(num, file, line);

78 79 80
    if (num <= 0)
        return NULL;

R
Rich Salz 已提交
81
    allow_customize = 0;
82
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
R
Rich Salz 已提交
83 84 85 86 87 88
    if (call_malloc_debug) {
        CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);
        ret = malloc(num);
        CRYPTO_mem_debug_malloc(ret, num, 1, file, line);
    } else {
        ret = malloc(num);
89
    }
R
Rich Salz 已提交
90
#else
91
    osslargused(file); osslargused(line);
R
Rich Salz 已提交
92 93
    ret = malloc(num);
#endif
94

95 96 97
    return ret;
}

98
void *CRYPTO_zalloc(size_t num, const char *file, int line)
R
Rich Salz 已提交
99 100 101 102 103 104 105 106
{
    void *ret = CRYPTO_malloc(num, file, line);

    if (ret != NULL)
        memset(ret, 0, num);
    return ret;
}

107
void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
108
{
109 110 111
    if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc)
        return realloc_impl(str, num, file, line);

112 113
    if (str == NULL)
        return CRYPTO_malloc(num, file, line);
114

R
Rich Salz 已提交
115
    if (num == 0) {
116
        CRYPTO_free(str, file, line);
117
        return NULL;
R
Rich Salz 已提交
118
    }
119

R
Rich Salz 已提交
120
    allow_customize = 0;
121
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
R
Rich Salz 已提交
122 123 124 125 126 127 128 129
    if (call_malloc_debug) {
        void *ret;
        CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);
        ret = realloc(str, num);
        CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line);
        return ret;
    }
#else
130
    osslargused(file); osslargused(line);
R
Rich Salz 已提交
131 132
#endif
    return realloc(str, num);
133

134
}
135

136
void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num,
137
                           const char *file, int line)
138 139 140 141 142 143
{
    void *ret = NULL;

    if (str == NULL)
        return CRYPTO_malloc(num, file, line);

R
Rich Salz 已提交
144
    if (num == 0) {
145
        CRYPTO_clear_free(str, old_len, file, line);
146
        return NULL;
R
Rich Salz 已提交
147
    }
148

R
Rich Salz 已提交
149 150
    /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */
    if (num < old_len) {
151
        OPENSSL_cleanse((char*)str + num, old_len - num);
R
Rich Salz 已提交
152 153
        return str;
    }
154

155
    ret = CRYPTO_malloc(num, file, line);
156
    if (ret != NULL) {
R
Rich Salz 已提交
157
        memcpy(ret, str, old_len);
158 159
        CRYPTO_clear_free(str, old_len, file, line);
    }
160 161
    return ret;
}
162

163
void CRYPTO_free(void *str, const char *file, int line)
164
{
165 166 167 168 169
    if (free_impl != NULL && free_impl != &CRYPTO_free) {
        free_impl(str, file, line);
        return;
    }

170
#ifndef OPENSSL_NO_CRYPTO_MDEBUG
R
Rich Salz 已提交
171
    if (call_malloc_debug) {
172
        CRYPTO_mem_debug_free(str, 0, file, line);
R
Rich Salz 已提交
173
        free(str);
174
        CRYPTO_mem_debug_free(str, 1, file, line);
R
Rich Salz 已提交
175 176 177 178 179 180
    } else {
        free(str);
    }
#else
    free(str);
#endif
181
}
182

183
void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)
R
Rich Salz 已提交
184
{
R
Rich Salz 已提交
185
    if (str == NULL)
R
Rich Salz 已提交
186 187 188
        return;
    if (num)
        OPENSSL_cleanse(str, num);
189
    CRYPTO_free(str, file, line);
R
Rich Salz 已提交
190
}