2 * Copyright 1995-2019 The OpenSSL Project Authors. All Rights Reserved.
4 * Licensed under the Apache License 2.0 (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
13 #include "internal/cryptlib.h"
14 #include "internal/thread_once.h"
15 #include <openssl/crypto.h>
16 #include <openssl/buffer.h>
17 #include "internal/bio.h"
18 #include <openssl/lhash.h>
20 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
21 # include <execinfo.h>
25 * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
26 * the application asks for it (usually after library initialisation for
27 * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
28 * temporarily when the library thinks that certain allocations should not be
29 * checked (e.g. the data structures used for memory checking). It is not
30 * suitable as an initial state: the library will unexpectedly enable memory
31 * checking when it executes one of those sections that want to disable
32 * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
33 * no sense whatsoever.
35 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
36 static int mh_mode = CRYPTO_MEM_CHECK_OFF;
39 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
40 static unsigned long order = 0; /* number of memory requests */
42 static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT;
43 CRYPTO_RWLOCK *memdbg_lock;
44 static CRYPTO_RWLOCK *long_memdbg_lock;
46 /* memory-block description */
52 CRYPTO_THREAD_ID threadid;
55 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
62 * hash-table of memory requests (address as * key); access requires
63 * long_memdbg_lock lock
65 static LHASH_OF(MEM) *mh = NULL;
67 /* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
68 static unsigned int num_disable = 0;
71 * Valid iff num_disable > 0. long_memdbg_lock is locked exactly in this
72 * case (by the thread named in disabling_thread).
74 static CRYPTO_THREAD_ID disabling_threadid;
76 DEFINE_RUN_ONCE_STATIC(do_memdbg_init)
78 memdbg_lock = CRYPTO_THREAD_lock_new();
79 long_memdbg_lock = CRYPTO_THREAD_lock_new();
80 if (memdbg_lock == NULL || long_memdbg_lock == NULL) {
81 CRYPTO_THREAD_lock_free(memdbg_lock);
83 CRYPTO_THREAD_lock_free(long_memdbg_lock);
84 long_memdbg_lock = NULL;
92 int CRYPTO_mem_ctrl(int mode)
94 #ifdef OPENSSL_NO_CRYPTO_MDEBUG
99 if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
102 CRYPTO_THREAD_write_lock(memdbg_lock);
107 case CRYPTO_MEM_CHECK_ON:
108 mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
112 case CRYPTO_MEM_CHECK_OFF:
117 /* switch off temporarily (for library-internal use): */
118 case CRYPTO_MEM_CHECK_DISABLE:
119 if (mh_mode & CRYPTO_MEM_CHECK_ON) {
120 CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
121 /* see if we don't have long_memdbg_lock already */
123 || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) {
125 * Long-time lock long_memdbg_lock must not be claimed
126 * while we're holding memdbg_lock, or we'll deadlock
127 * if somebody else holds long_memdbg_lock (and cannot
128 * release it because we block entry to this function). Give
129 * them a chance, first, and then claim the locks in
130 * appropriate order (long-time lock first).
132 CRYPTO_THREAD_unlock(memdbg_lock);
134 * Note that after we have waited for long_memdbg_lock and
135 * memdbg_lock, we'll still be in the right "case" and
136 * "if" branch because MemCheck_start and MemCheck_stop may
137 * never be used while there are multiple OpenSSL threads.
139 CRYPTO_THREAD_write_lock(long_memdbg_lock);
140 CRYPTO_THREAD_write_lock(memdbg_lock);
141 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
142 disabling_threadid = cur;
148 case CRYPTO_MEM_CHECK_ENABLE:
149 if (mh_mode & CRYPTO_MEM_CHECK_ON) {
150 if (num_disable) { /* always true, or something is going wrong */
152 if (num_disable == 0) {
153 mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
154 CRYPTO_THREAD_unlock(long_memdbg_lock);
160 CRYPTO_THREAD_unlock(memdbg_lock);
165 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
167 static int mem_check_on(void)
170 CRYPTO_THREAD_ID cur;
172 if (mh_mode & CRYPTO_MEM_CHECK_ON) {
173 if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
176 cur = CRYPTO_THREAD_get_current_id();
177 CRYPTO_THREAD_read_lock(memdbg_lock);
179 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
180 || !CRYPTO_THREAD_compare_id(disabling_threadid, cur);
182 CRYPTO_THREAD_unlock(memdbg_lock);
187 static int mem_cmp(const MEM *a, const MEM *b)
190 const char *ap = (const char *)a->addr, *bp = (const char *)b->addr;
198 return (const char *)a->addr - (const char *)b->addr;
202 static unsigned long mem_hash(const MEM *a)
206 ret = (size_t)a->addr;
208 ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
212 int CRYPTO_mem_debug_push(const char *info, const char *file, int line)
217 int CRYPTO_mem_debug_pop(void)
222 static unsigned long break_order_num = 0;
224 void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p,
225 const char *file, int line)
229 switch (before_p & 127) {
236 if (mem_check_on()) {
237 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
239 if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
240 || (m = OPENSSL_malloc(sizeof(*m))) == NULL) {
242 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
246 if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) {
258 m->threadid = CRYPTO_THREAD_get_current_id();
260 if (order == break_order_num) {
265 # ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
266 m->array_siz = backtrace(m->array, OSSL_NELEM(m->array));
268 m->time = time(NULL);
270 if ((mm = lh_MEM_insert(mh, m)) != NULL)
273 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
280 void CRYPTO_mem_debug_free(void *addr, int before_p,
281 const char *file, int line)
290 if (mem_check_on() && (mh != NULL)) {
291 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
293 mp = lh_MEM_delete(mh, &m);
295 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
303 void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num,
304 int before_p, const char *file, int line)
316 CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line);
320 if (mem_check_on()) {
321 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
324 mp = lh_MEM_delete(mh, &m);
328 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
329 mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array));
331 (void)lh_MEM_insert(mh, mp);
334 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
341 typedef struct mem_leak_st {
342 int (*print_cb) (const char *str, size_t len, void *u);
348 static void print_leak(const MEM *m, MEM_LEAK *l)
351 char *bufp = buf, *hex;
352 size_t len = sizeof(buf);
354 struct tm *lcl = NULL;
356 lcl = localtime(&m->time);
357 n = BIO_snprintf(bufp, len, "[%02d:%02d:%02d] ",
358 lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
366 n = BIO_snprintf(bufp, len, "%5lu file=%s, line=%d, ",
367 m->order, m->file, m->line);
373 hex = OPENSSL_buf2hexstr((const unsigned char *)&m->threadid,
374 sizeof(m->threadid));
375 n = BIO_snprintf(bufp, len, "thread=%s, number=%d, address=%p\n", hex,
383 l->print_cb(buf, (size_t)(bufp - buf), l->print_cb_arg);
387 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
390 char **strings = backtrace_symbols(m->array, m->array_siz);
392 for (i = 0; i < m->array_siz; i++)
393 fprintf(stderr, "##> %s\n", strings[i]);
399 IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK);
401 int CRYPTO_mem_leaks_cb(int (*cb) (const char *str, size_t len, void *u),
406 /* Ensure all resources are released */
409 if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
412 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
419 lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml);
421 if (ml.chunks != 0) {
424 BIO_snprintf(buf, sizeof(buf), "%ld bytes leaked in %d chunks\n",
425 ml.bytes, ml.chunks);
426 cb(buf, strlen(buf), u);
429 * Make sure that, if we found no leaks, memory-leak debugging itself
430 * does not introduce memory leaks (which might irritate external
431 * debugging tools). (When someone enables leak checking, but does not
432 * call this function, we declare it to be their fault.)
436 CRYPTO_THREAD_write_lock(memdbg_lock);
439 * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses
442 old_mh_mode = mh_mode;
443 mh_mode = CRYPTO_MEM_CHECK_OFF;
448 mh_mode = old_mh_mode;
449 CRYPTO_THREAD_unlock(memdbg_lock);
451 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
453 /* Clean up locks etc */
454 CRYPTO_THREAD_lock_free(memdbg_lock);
455 CRYPTO_THREAD_lock_free(long_memdbg_lock);
457 long_memdbg_lock = NULL;
459 return ml.chunks == 0 ? 1 : 0;
462 static int print_bio(const char *str, size_t len, void *b)
464 return BIO_write((BIO *)b, str, len);
467 int CRYPTO_mem_leaks(BIO *b)
470 * OPENSSL_cleanup() will free the ex_data locks so we can't have any
471 * ex_data hanging around
475 return CRYPTO_mem_leaks_cb(print_bio, b);
478 # ifndef OPENSSL_NO_STDIO
479 int CRYPTO_mem_leaks_fp(FILE *fp)
485 * Need to turn off memory checking when allocated BIOs ... especially as
486 * we're creating them at a time when we're trying to check we've not
487 * left anything un-free()'d!!
489 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
490 b = BIO_new(BIO_s_file());
491 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
494 BIO_set_fp(b, fp, BIO_NOCLOSE);
495 ret = CRYPTO_mem_leaks_cb(print_bio, b);