VirtualBox

source: vbox/trunk/src/libs/openssl-1.1.1g/crypto/mem.c@ 85622

Last change on this file since 85622 was 83916, checked in by vboxsync, 5 years ago

openssl-1.1.1g: Applied and adjusted our OpenSSL changes to 1.1.1g. bugref:9719

File size: 7.8 KB
Line 
1/*
2 * Copyright 1995-2018 The OpenSSL Project Authors. All Rights Reserved.
3 *
4 * Licensed under the OpenSSL license (the "License"). You may not use
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
8 */
9
10#include "e_os.h"
11#include "internal/cryptlib.h"
12#include <stdio.h>
13#include <stdlib.h>
14#include <limits.h>#include <openssl/crypto.h>
15#ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
16# include <execinfo.h>
17#endif
18
19/*
20 * the following pointers may be changed as long as 'allow_customize' is set
21 */
22static int allow_customize = 1;
23
24static void *(*malloc_impl)(size_t, const char *, int)
25 = CRYPTO_malloc;
26static void *(*realloc_impl)(void *, size_t, const char *, int)
27 = CRYPTO_realloc;
28static void (*free_impl)(void *, const char *, int)
29 = CRYPTO_free;
30
31#ifndef OPENSSL_NO_CRYPTO_MDEBUG
32# include "internal/tsan_assist.h"
33
34static TSAN_QUALIFIER int malloc_count;
35static TSAN_QUALIFIER int realloc_count;
36static TSAN_QUALIFIER int free_count;
37
38# define INCREMENT(x) tsan_counter(&(x))
39
40static char *md_failstring;
41static long md_count;
42static int md_fail_percent = 0;
43static int md_tracefd = -1;
44static int call_malloc_debug = 1;
45
46static void parseit(void);
47static int shouldfail(void);
48
49# define FAILTEST() if (shouldfail()) return NULL
50
51#else
52static int call_malloc_debug = 0;
53
54# define INCREMENT(x) /* empty */
55# define FAILTEST() /* empty */
56#endif
57
58int CRYPTO_set_mem_functions(
59 void *(*m)(size_t, const char *, int),
60 void *(*r)(void *, size_t, const char *, int),
61 void (*f)(void *, const char *, int))
62{
63 if (!allow_customize)
64 return 0;
65 if (m)
66 malloc_impl = m;
67 if (r)
68 realloc_impl = r;
69 if (f)
70 free_impl = f;
71 return 1;
72}
73
74int CRYPTO_set_mem_debug(int flag)
75{
76 if (!allow_customize)
77 return 0;
78 call_malloc_debug = flag;
79 return 1;
80}
81
82void CRYPTO_get_mem_functions(
83 void *(**m)(size_t, const char *, int),
84 void *(**r)(void *, size_t, const char *, int),
85 void (**f)(void *, const char *, int))
86{
87 if (m != NULL)
88 *m = malloc_impl;
89 if (r != NULL)
90 *r = realloc_impl;
91 if (f != NULL)
92 *f = free_impl;
93}
94
95#ifndef OPENSSL_NO_CRYPTO_MDEBUG
96void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount)
97{
98 if (mcount != NULL)
99 *mcount = tsan_load(&malloc_count);
100 if (rcount != NULL)
101 *rcount = tsan_load(&realloc_count);
102 if (fcount != NULL)
103 *fcount = tsan_load(&free_count);
104}
105
106/*
107 * Parse a "malloc failure spec" string. This likes like a set of fields
108 * separated by semicolons. Each field has a count and an optional failure
109 * percentage. For example:
110 * 100@0;100@25;0@0
111 * or 100;100@25;0
112 * This means 100 mallocs succeed, then next 100 fail 25% of the time, and
113 * all remaining (count is zero) succeed.
114 */
115static void parseit(void)
116{
117 char *semi = strchr(md_failstring, ';');
118 char *atsign;
119
120 if (semi != NULL)
121 *semi++ = '\0';
122
123 /* Get the count (atol will stop at the @ if there), and percentage */
124 md_count = atol(md_failstring);
125 atsign = strchr(md_failstring, '@');
126 md_fail_percent = atsign == NULL ? 0 : atoi(atsign + 1);
127
128 if (semi != NULL)
129 md_failstring = semi;
130}
131
132/*
133 * Windows doesn't have random(), but it has rand()
134 * Some rand() implementations aren't good, but we're not
135 * dealing with secure randomness here.
136 */
137# ifdef _WIN32
138# define random() rand()
139# endif
140/*
141 * See if the current malloc should fail.
142 */
143static int shouldfail(void)
144{
145 int roll = (int)(random() % 100);
146 int shoulditfail = roll < md_fail_percent;
147# ifndef _WIN32
148/* suppressed on Windows as POSIX-like file descriptors are non-inheritable */
149 int len;
150 char buff[80];
151
152 if (md_tracefd > 0) {
153 BIO_snprintf(buff, sizeof(buff),
154 "%c C%ld %%%d R%d\n",
155 shoulditfail ? '-' : '+', md_count, md_fail_percent, roll);
156 len = strlen(buff);
157 if (write(md_tracefd, buff, len) != len)
158 perror("shouldfail write failed");
159# ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
160 if (shoulditfail) {
161 void *addrs[30];
162 int num = backtrace(addrs, OSSL_NELEM(addrs));
163
164 backtrace_symbols_fd(addrs, num, md_tracefd);
165 }
166# endif
167 }
168# endif
169
170 if (md_count) {
171 /* If we used up this one, go to the next. */
172 if (--md_count == 0)
173 parseit();
174 }
175
176 return shoulditfail;
177}
178
179void ossl_malloc_setup_failures(void)
180{
181 const char *cp = getenv("OPENSSL_MALLOC_FAILURES");
182
183 if (cp != NULL && (md_failstring = strdup(cp)) != NULL)
184 parseit();
185 if ((cp = getenv("OPENSSL_MALLOC_FD")) != NULL)
186 md_tracefd = atoi(cp);
187}
188#endif
189
190void *CRYPTO_malloc(size_t num, const char *file, int line)
191{
192 void *ret = NULL;
193
194 INCREMENT(malloc_count);
195 if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
196 return malloc_impl(num, file, line);
197
198 if (num == 0)
199 return NULL;
200
201 FAILTEST();
202 if (allow_customize) {
203 /*
204 * Disallow customization after the first allocation. We only set this
205 * if necessary to avoid a store to the same cache line on every
206 * allocation.
207 */
208 allow_customize = 0;
209 }
210#ifndef OPENSSL_NO_CRYPTO_MDEBUG
211 if (call_malloc_debug) {
212 CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);
213 ret = malloc(num);
214 CRYPTO_mem_debug_malloc(ret, num, 1, file, line);
215 } else {
216 ret = malloc(num);
217 }
218#else
219 (void)(file); (void)(line);
220 ret = malloc(num);
221#endif
222
223 return ret;
224}
225
226void *CRYPTO_zalloc(size_t num, const char *file, int line)
227{
228 void *ret = CRYPTO_malloc(num, file, line);
229
230 FAILTEST();
231 if (ret != NULL)
232 memset(ret, 0, num);
233 return ret;
234}
235
236void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
237{
238 INCREMENT(realloc_count);
239 if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc)
240 return realloc_impl(str, num, file, line);
241
242 FAILTEST();
243 if (str == NULL)
244 return CRYPTO_malloc(num, file, line);
245
246 if (num == 0) {
247 CRYPTO_free(str, file, line);
248 return NULL;
249 }
250
251#ifndef OPENSSL_NO_CRYPTO_MDEBUG
252 if (call_malloc_debug) {
253 void *ret;
254 CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);
255 ret = realloc(str, num);
256 CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line);
257 return ret;
258 }
259#else
260 (void)(file); (void)(line);
261#endif
262 return realloc(str, num);
263
264}
265
266void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num,
267 const char *file, int line)
268{
269 void *ret = NULL;
270
271 if (str == NULL)
272 return CRYPTO_malloc(num, file, line);
273
274 if (num == 0) {
275 CRYPTO_clear_free(str, old_len, file, line);
276 return NULL;
277 }
278
279 /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */
280 if (num < old_len) {
281 OPENSSL_cleanse((char*)str + num, old_len - num);
282 return str;
283 }
284
285 ret = CRYPTO_malloc(num, file, line);
286 if (ret != NULL) {
287 memcpy(ret, str, old_len);
288 CRYPTO_clear_free(str, old_len, file, line);
289 }
290 return ret;
291}
292
293void CRYPTO_free(void *str, const char *file, int line)
294{
295 INCREMENT(free_count);
296 if (free_impl != NULL && free_impl != &CRYPTO_free) {
297 free_impl(str, file, line);
298 return;
299 }
300
301#ifndef OPENSSL_NO_CRYPTO_MDEBUG
302 if (call_malloc_debug) {
303 CRYPTO_mem_debug_free(str, 0, file, line);
304 free(str);
305 CRYPTO_mem_debug_free(str, 1, file, line);
306 } else {
307 free(str);
308 }
309#else
310 free(str);
311#endif
312}
313
314void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)
315{
316 if (str == NULL)
317 return;
318 if (num)
319 OPENSSL_cleanse(str, num);
320 CRYPTO_free(str, file, line);
321}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette