]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/mem.c
Rework and make DEBUG macros consistent.
[thirdparty/openssl.git] / crypto / mem.c
CommitLineData
4f22f405 1/*
33388b44 2 * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
d02b48c6 3 *
0e9725bc 4 * Licensed under the Apache License 2.0 (the "License"). You may not use
4f22f405
RS
5 * this file except in compliance with the License. You can obtain a copy
6 * in the file LICENSE in the source distribution or at
7 * https://www.openssl.org/source/license.html
d02b48c6
RE
8 */
9
07016a8a
P
10#include "e_os.h"
11#include "internal/cryptlib.h"
25f2138b 12#include "crypto/cryptlib.h"
d02b48c6
RE
13#include <stdio.h>
14#include <stdlib.h>
bbd86bf5 15#include <limits.h>
458cddc1 16#include <openssl/crypto.h>
d02b48c6 17
0f113f3e
MC
18/*
19 * the following pointers may be changed as long as 'allow_customize' is set
20 */
bbd86bf5 21static int allow_customize = 1;
f4dcc09b
DG
22static CRYPTO_malloc_fn malloc_impl = CRYPTO_malloc;
23static CRYPTO_realloc_fn realloc_impl = CRYPTO_realloc;
24static CRYPTO_free_fn free_impl = CRYPTO_free;
74924dcb 25
f844f9eb 26#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODULE)
8f154985 27# include "internal/tsan_assist.h"
0e598a3d 28
8f154985
AP
29static TSAN_QUALIFIER int malloc_count;
30static TSAN_QUALIFIER int realloc_count;
31static TSAN_QUALIFIER int free_count;
32
33# define INCREMENT(x) tsan_counter(&(x))
0e598a3d 34
f7edeced
RS
35static char *md_failstring;
36static long md_count;
50718243 37static int md_fail_percent = 0;
f7edeced 38static int md_tracefd = -1;
f7edeced
RS
39
40static void parseit(void);
41static int shouldfail(void);
42
43# define FAILTEST() if (shouldfail()) return NULL
44
f3a2a044 45#else
f7edeced 46
0e598a3d 47# define INCREMENT(x) /* empty */
f7edeced 48# define FAILTEST() /* empty */
f3a2a044 49#endif
9ac42ed8 50
f4dcc09b
DG
51int CRYPTO_set_mem_functions(CRYPTO_malloc_fn malloc_fn,
52 CRYPTO_realloc_fn realloc_fn,
53 CRYPTO_free_fn free_fn)
74924dcb 54{
74924dcb
RS
55 if (!allow_customize)
56 return 0;
f4dcc09b
DG
57 if (malloc_fn != NULL)
58 malloc_impl = malloc_fn;
59 if (realloc_fn != NULL)
60 realloc_impl = realloc_fn;
61 if (free_fn != NULL)
62 free_impl = free_fn;
74924dcb
RS
63 return 1;
64}
65
f4dcc09b
DG
66void CRYPTO_get_mem_functions(CRYPTO_malloc_fn *malloc_fn,
67 CRYPTO_realloc_fn *realloc_fn,
68 CRYPTO_free_fn *free_fn)
0f113f3e 69{
f4dcc09b
DG
70 if (malloc_fn != NULL)
71 *malloc_fn = malloc_impl;
72 if (realloc_fn != NULL)
73 *realloc_fn = realloc_impl;
74 if (free_fn != NULL)
75 *free_fn = free_impl;
0f113f3e 76}
d02b48c6 77
f844f9eb 78#if !defined(OPENSSL_NO_CRYPTO_MDEBUG) && !defined(FIPS_MODULE)
0e598a3d
RS
79void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount)
80{
81 if (mcount != NULL)
8f154985 82 *mcount = tsan_load(&malloc_count);
0e598a3d 83 if (rcount != NULL)
8f154985 84 *rcount = tsan_load(&realloc_count);
0e598a3d 85 if (fcount != NULL)
8f154985 86 *fcount = tsan_load(&free_count);
0e598a3d
RS
87}
88
f7edeced
RS
89/*
90 * Parse a "malloc failure spec" string. This likes like a set of fields
91 * separated by semicolons. Each field has a count and an optional failure
92 * percentage. For example:
50718243
RS
93 * 100@0;100@25;0@0
94 * or 100;100@25;0
f7edeced
RS
95 * This means 100 mallocs succeed, then next 100 fail 25% of the time, and
96 * all remaining (count is zero) succeed.
97 */
98static void parseit(void)
99{
100 char *semi = strchr(md_failstring, ';');
101 char *atsign;
102
103 if (semi != NULL)
104 *semi++ = '\0';
105
106 /* Get the count (atol will stop at the @ if there), and percentage */
107 md_count = atol(md_failstring);
108 atsign = strchr(md_failstring, '@');
50718243 109 md_fail_percent = atsign == NULL ? 0 : atoi(atsign + 1);
f7edeced
RS
110
111 if (semi != NULL)
112 md_failstring = semi;
113}
114
afe9bba7
RL
115/*
116 * Windows doesn't have random(), but it has rand()
117 * Some rand() implementations aren't good, but we're not
118 * dealing with secure randomness here.
119 */
ab307dc6
DO
120# ifdef _WIN32
121# define random() rand()
122# endif
f7edeced
RS
123/*
124 * See if the current malloc should fail.
125 */
126static int shouldfail(void)
127{
128 int roll = (int)(random() % 100);
d2b53fcd 129 int shoulditfail = roll < md_fail_percent;
ab307dc6
DO
130# ifndef _WIN32
131/* suppressed on Windows as POSIX-like file descriptors are non-inheritable */
43a0449f 132 int len;
f7edeced
RS
133 char buff[80];
134
135 if (md_tracefd > 0) {
136 BIO_snprintf(buff, sizeof(buff),
137 "%c C%ld %%%d R%d\n",
d2b53fcd 138 shoulditfail ? '-' : '+', md_count, md_fail_percent, roll);
43a0449f
P
139 len = strlen(buff);
140 if (write(md_tracefd, buff, len) != len)
141 perror("shouldfail write failed");
f7edeced 142 }
ab307dc6 143# endif
f7edeced
RS
144
145 if (md_count) {
146 /* If we used up this one, go to the next. */
147 if (--md_count == 0)
148 parseit();
149 }
150
d2b53fcd 151 return shoulditfail;
f7edeced
RS
152}
153
154void ossl_malloc_setup_failures(void)
155{
156 const char *cp = getenv("OPENSSL_MALLOC_FAILURES");
157
158 if (cp != NULL && (md_failstring = strdup(cp)) != NULL)
159 parseit();
160 if ((cp = getenv("OPENSSL_MALLOC_FD")) != NULL)
161 md_tracefd = atoi(cp);
162}
163#endif
164
ff842856 165void *CRYPTO_malloc(size_t num, const char *file, int line)
0f113f3e 166{
0e598a3d 167 INCREMENT(malloc_count);
f4dcc09b 168 if (malloc_impl != CRYPTO_malloc)
05c7b163
RL
169 return malloc_impl(num, file, line);
170
5e1f879a 171 if (num == 0)
0f113f3e
MC
172 return NULL;
173
f7edeced 174 FAILTEST();
41aede86 175 if (allow_customize) {
176 /*
177 * Disallow customization after the first allocation. We only set this
178 * if necessary to avoid a store to the same cache line on every
179 * allocation.
180 */
181 allow_customize = 0;
182 }
d02b48c6 183
f4dcc09b 184 return malloc(num);
0f113f3e
MC
185}
186
ff842856 187void *CRYPTO_zalloc(size_t num, const char *file, int line)
b51bce94 188{
f4dcc09b 189 void *ret;
b51bce94 190
f4dcc09b 191 ret = CRYPTO_malloc(num, file, line);
f7edeced 192 FAILTEST();
b51bce94
RS
193 if (ret != NULL)
194 memset(ret, 0, num);
f4dcc09b 195
b51bce94
RS
196 return ret;
197}
198
ff842856 199void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
0f113f3e 200{
0e598a3d 201 INCREMENT(realloc_count);
f4dcc09b 202 if (realloc_impl != CRYPTO_realloc)
05c7b163
RL
203 return realloc_impl(str, num, file, line);
204
f7edeced 205 FAILTEST();
0f113f3e
MC
206 if (str == NULL)
207 return CRYPTO_malloc(num, file, line);
d5234c7b 208
bbd86bf5 209 if (num == 0) {
05c7b163 210 CRYPTO_free(str, file, line);
0f113f3e 211 return NULL;
bbd86bf5 212 }
d5234c7b 213
bbd86bf5 214 return realloc(str, num);
0f113f3e 215}
d02b48c6 216
c99de053 217void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num,
ff842856 218 const char *file, int line)
0f113f3e
MC
219{
220 void *ret = NULL;
221
222 if (str == NULL)
223 return CRYPTO_malloc(num, file, line);
224
bbd86bf5 225 if (num == 0) {
05c7b163 226 CRYPTO_clear_free(str, old_len, file, line);
0f113f3e 227 return NULL;
bbd86bf5 228 }
0f113f3e 229
bbd86bf5
RS
230 /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */
231 if (num < old_len) {
3ce2fdab 232 OPENSSL_cleanse((char*)str + num, old_len - num);
bbd86bf5
RS
233 return str;
234 }
0f113f3e 235
05c7b163 236 ret = CRYPTO_malloc(num, file, line);
2ac7753c 237 if (ret != NULL) {
bbd86bf5 238 memcpy(ret, str, old_len);
2ac7753c
DSH
239 CRYPTO_clear_free(str, old_len, file, line);
240 }
0f113f3e
MC
241 return ret;
242}
54a656ef 243
05c7b163 244void CRYPTO_free(void *str, const char *file, int line)
0f113f3e 245{
0e598a3d 246 INCREMENT(free_count);
f4dcc09b 247 if (free_impl != CRYPTO_free) {
05c7b163
RL
248 free_impl(str, file, line);
249 return;
250 }
251
bbd86bf5 252 free(str);
0f113f3e 253}
d02b48c6 254
05c7b163 255void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)
4b45c6e5 256{
bbd86bf5 257 if (str == NULL)
4b45c6e5
RS
258 return;
259 if (num)
260 OPENSSL_cleanse(str, num);
05c7b163 261 CRYPTO_free(str, file, line);
4b45c6e5 262}
742ccab3
RS
263
264#if !defined(OPENSSL_NO_CRYPTO_MDEBUG)
265
266# ifndef OPENSSL_NO_DEPRECATED_3_0
267int CRYPTO_mem_ctrl(int mode)
268{
269 (void)mode;
270 return -1;
271}
272
273int CRYPTO_set_mem_debug(int flag)
274{
275 (void)flag;
276 return -1;
277}
278
279int CRYPTO_mem_debug_push(const char *info, const char *file, int line)
280{
281 (void)info; (void)file; (void)line;
282 return -1;
283}
284
285int CRYPTO_mem_debug_pop(void)
286{
287 return -1;
288}
289
f64f2622
RS
290void CRYPTO_mem_debug_malloc(void *addr, size_t num, int flag,
291 const char *file, int line)
292{
293 (void)addr; (void)num; (void)flag; (void)file; (void)line;
294}
295
296void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num, int flag,
297 const char *file, int line)
298{
299 (void)addr1; (void)addr2; (void)num; (void)flag; (void)file; (void)line;
300}
301
302void CRYPTO_mem_debug_free(void *addr, int flag,
303 const char *file, int line)
304{
305 (void)addr; (void)flag; (void)file; (void)line;
306}
307
742ccab3
RS
308int CRYPTO_mem_leaks(BIO *b)
309{
310 (void)b;
311 return -1;
312}
313
314# ifndef OPENSSL_NO_STDIO
315int CRYPTO_mem_leaks_fp(FILE *fp)
316{
317 (void)fp;
318 return -1;
319}
320# endif
321
322int CRYPTO_mem_leaks_cb(int (*cb)(const char *str, size_t len, void *u),
323 void *u)
324{
325 (void)cb; (void)u;
326 return -1;
327}
328
329# endif
330
331#endif