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;
213 int CRYPTO_mem_debug_push(const char *info
, const char *file
, int line
)
218 int CRYPTO_mem_debug_pop(void)
224 static unsigned long break_order_num
= 0;
226 void CRYPTO_mem_debug_malloc(void *addr
, size_t num
, int before_p
,
227 const char *file
, int line
)
231 switch (before_p
& 127) {
238 if (mem_check_on()) {
239 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE
);
241 if (!RUN_ONCE(&memdbg_init
, do_memdbg_init
)
242 || (m
= OPENSSL_malloc(sizeof(*m
))) == NULL
) {
244 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE
);
248 if ((mh
= lh_MEM_new(mem_hash
, mem_cmp
)) == NULL
) {
260 m
->threadid
= CRYPTO_THREAD_get_current_id();
262 if (order
== break_order_num
) {
267 # ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
268 m
->array_siz
= backtrace(m
->array
, OSSL_NELEM(m
->array
));
270 m
->time
= time(NULL
);
272 if ((mm
= lh_MEM_insert(mh
, m
)) != NULL
)
275 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE
);
282 void CRYPTO_mem_debug_free(void *addr
, int before_p
,
283 const char *file
, int line
)
292 if (mem_check_on() && (mh
!= NULL
)) {
293 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE
);
295 mp
= lh_MEM_delete(mh
, &m
);
297 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE
);
305 void CRYPTO_mem_debug_realloc(void *addr1
, void *addr2
, size_t num
,
306 int before_p
, const char *file
, int line
)
318 CRYPTO_mem_debug_malloc(addr2
, num
, 128 | before_p
, file
, line
);
322 if (mem_check_on()) {
323 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE
);
326 mp
= lh_MEM_delete(mh
, &m
);
330 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
331 mp
->array_siz
= backtrace(mp
->array
, OSSL_NELEM(mp
->array
));
333 (void)lh_MEM_insert(mh
, mp
);
336 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE
);
343 typedef struct mem_leak_st
{
344 int (*print_cb
) (const char *str
, size_t len
, void *u
);
350 static void print_leak(const MEM
*m
, MEM_LEAK
*l
)
353 char *bufp
= buf
, *hex
;
354 size_t len
= sizeof(buf
);
356 struct tm
*lcl
= NULL
;
358 lcl
= localtime(&m
->time
);
359 n
= BIO_snprintf(bufp
, len
, "[%02d:%02d:%02d] ",
360 lcl
->tm_hour
, lcl
->tm_min
, lcl
->tm_sec
);
368 n
= BIO_snprintf(bufp
, len
, "%5lu file=%s, line=%d, ",
369 m
->order
, m
->file
, m
->line
);
375 hex
= OPENSSL_buf2hexstr((const unsigned char *)&m
->threadid
,
376 sizeof(m
->threadid
));
377 n
= BIO_snprintf(bufp
, len
, "thread=%s, number=%d, address=%p\n", hex
,
385 l
->print_cb(buf
, (size_t)(bufp
- buf
), l
->print_cb_arg
);
389 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
392 char **strings
= backtrace_symbols(m
->array
, m
->array_siz
);
394 for (i
= 0; i
< m
->array_siz
; i
++)
395 fprintf(stderr
, "##> %s\n", strings
[i
]);
401 IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM
, MEM_LEAK
);
403 int CRYPTO_mem_leaks_cb(int (*cb
) (const char *str
, size_t len
, void *u
),
408 /* Ensure all resources are released */
411 if (!RUN_ONCE(&memdbg_init
, do_memdbg_init
))
414 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE
);
421 lh_MEM_doall_MEM_LEAK(mh
, print_leak
, &ml
);
423 if (ml
.chunks
!= 0) {
426 BIO_snprintf(buf
, sizeof(buf
), "%ld bytes leaked in %d chunks\n",
427 ml
.bytes
, ml
.chunks
);
428 cb(buf
, strlen(buf
), u
);
431 * Make sure that, if we found no leaks, memory-leak debugging itself
432 * does not introduce memory leaks (which might irritate external
433 * debugging tools). (When someone enables leak checking, but does not
434 * call this function, we declare it to be their fault.)
438 CRYPTO_THREAD_write_lock(memdbg_lock
);
441 * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses
444 old_mh_mode
= mh_mode
;
445 mh_mode
= CRYPTO_MEM_CHECK_OFF
;
450 mh_mode
= old_mh_mode
;
451 CRYPTO_THREAD_unlock(memdbg_lock
);
453 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF
);
455 /* Clean up locks etc */
456 CRYPTO_THREAD_lock_free(memdbg_lock
);
457 CRYPTO_THREAD_lock_free(long_memdbg_lock
);
459 long_memdbg_lock
= NULL
;
461 return ml
.chunks
== 0 ? 1 : 0;
464 static int print_bio(const char *str
, size_t len
, void *b
)
466 return BIO_write((BIO
*)b
, str
, len
);
469 int CRYPTO_mem_leaks(BIO
*b
)
472 * OPENSSL_cleanup() will free the ex_data locks so we can't have any
473 * ex_data hanging around
477 return CRYPTO_mem_leaks_cb(print_bio
, b
);
480 # ifndef OPENSSL_NO_STDIO
481 int CRYPTO_mem_leaks_fp(FILE *fp
)
487 * Need to turn off memory checking when allocated BIOs ... especially as
488 * we're creating them at a time when we're trying to check we've not
489 * left anything un-free()'d!!
491 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE
);
492 b
= BIO_new(BIO_s_file());
493 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE
);
496 BIO_set_fp(b
, fp
, BIO_NOCLOSE
);
497 ret
= CRYPTO_mem_leaks_cb(print_bio
, b
);