2
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
5
* This package is an SSL implementation written
6
* by Eric Young (eay@cryptsoft.com).
7
* The implementation was written so as to conform with Netscapes SSL.
9
* This library is free for commercial and non-commercial use as long as
10
* the following conditions are aheared to. The following conditions
11
* apply to all code found in this distribution, be it the RC4, RSA,
12
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
13
* included with this distribution is covered by the same copyright terms
14
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
16
* Copyright remains Eric Young's, and as such any Copyright notices in
17
* the code are not to be removed.
18
* If this package is used in a product, Eric Young should be given attribution
19
* as the author of the parts of the library used.
20
* This can be in the form of a textual message at program startup or
21
* in documentation (online or textual) provided with the package.
23
* Redistribution and use in source and binary forms, with or without
24
* modification, are permitted provided that the following conditions
26
* 1. Redistributions of source code must retain the copyright
27
* notice, this list of conditions and the following disclaimer.
28
* 2. Redistributions in binary form must reproduce the above copyright
29
* notice, this list of conditions and the following disclaimer in the
30
* documentation and/or other materials provided with the distribution.
31
* 3. All advertising materials mentioning features or use of this software
32
* must display the following acknowledgement:
33
* "This product includes cryptographic software written by
34
* Eric Young (eay@cryptsoft.com)"
35
* The word 'cryptographic' can be left out if the rouines from the library
36
* being used are not cryptographic related :-).
37
* 4. If you include any Windows specific code (or a derivative thereof) from
38
* the apps directory (application code) you must include an acknowledgement:
39
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
41
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53
* The licence and distribution terms for any publically available version or
54
* derivative of this code cannot be changed. i.e. this code cannot simply be
55
* copied and put under another distribution licence
56
* [including the GNU Public Licence.]
63
#include <openssl/crypto.h>
64
#include <openssl/buffer.h>
65
#include <openssl/bio.h>
66
#include <openssl/lhash.h>
68
static int mh_mode=CRYPTO_MEM_CHECK_OFF;
69
/* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
70
* when the application asks for it (usually after library initialisation
71
* for which no book-keeping is desired).
73
* State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
74
* thinks that certain allocations should not be checked (e.g. the data
75
* structures used for memory checking). It is not suitable as an initial
76
* state: the library will unexpectedly enable memory checking when it
77
* executes one of those sections that want to disable checking
80
* State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
83
static unsigned long order = 0; /* number of memory requests */
84
static LHASH *mh=NULL; /* hash-table of memory requests (address as key);
85
* access requires MALLOC2 lock */
88
typedef struct app_mem_info_st
89
/* For application-defined information (static C-string `info')
90
* to be displayed in memory leak list.
91
* Each thread has its own stack. For applications, there is
92
* CRYPTO_push_info("...") to push an entry,
93
* CRYPTO_pop_info() to pop an entry,
94
* CRYPTO_remove_all_info() to pop all entries.
101
struct app_mem_info_st *next; /* tail of thread's stack */
105
static void app_info_free(APP_INFO *);
107
static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
108
* that are at the top of their thread's stack
109
* (with `thread' as key);
110
* access requires MALLOC2 lock */
112
typedef struct mem_st
113
/* memory-block description */
119
unsigned long thread;
125
static long options = /* extra information to be recorded */
126
#if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
127
V_CRYPTO_MDEBUG_TIME |
129
#if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
130
V_CRYPTO_MDEBUG_THREAD |
135
static unsigned int num_disable = 0; /* num_disable > 0
137
* mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
139
static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0.
140
* CRYPTO_LOCK_MALLOC2 is locked
141
* exactly in this case (by the
142
* thread named in disabling_thread).
145
static void app_info_free(APP_INFO *inf)
147
if (--(inf->references) <= 0)
149
if (inf->next != NULL)
151
app_info_free(inf->next);
157
int CRYPTO_mem_ctrl(int mode)
161
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
164
/* for applications (not to be called while multiple threads
165
* use the library): */
166
case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
167
mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
170
case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
172
num_disable = 0; /* should be true *before* MemCheck_stop is used,
173
or there'll be a lot of confusion */
176
/* switch off temporarily (for library-internal use): */
177
case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
178
if (mh_mode & CRYPTO_MEM_CHECK_ON)
180
if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */
182
/* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
183
* we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
184
* somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
185
* it because we block entry to this function).
186
* Give them a chance, first, and then claim the locks in
187
* appropriate order (long-time lock first).
189
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
190
/* Note that after we have waited for CRYPTO_LOCK_MALLOC2
191
* and CRYPTO_LOCK_MALLOC, we'll still be in the right
192
* "case" and "if" branch because MemCheck_start and
193
* MemCheck_stop may never be used while there are multiple
194
* OpenSSL threads. */
195
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
196
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
197
mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
198
disabling_thread=CRYPTO_thread_id();
203
case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
204
if (mh_mode & CRYPTO_MEM_CHECK_ON)
206
if (num_disable) /* always true, or something is going wrong */
209
if (num_disable == 0)
211
mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
212
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
221
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
225
int CRYPTO_is_mem_check_on(void)
229
if (mh_mode & CRYPTO_MEM_CHECK_ON)
231
CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
233
ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
234
|| (disabling_thread != CRYPTO_thread_id());
236
CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
242
void CRYPTO_dbg_set_options(long bits)
247
long CRYPTO_dbg_get_options(void)
252
/* static int mem_cmp(MEM *a, MEM *b) */
253
static int mem_cmp(const void *a_void, const void *b_void)
256
const char *a=(const char *)((const MEM *)a_void)->addr,
257
*b=(const char *)((const MEM *)b_void)->addr;
259
else if (a>b) return 1;
262
return((const char *)((const MEM *)a_void)->addr
263
- (const char *)((const MEM *)b_void)->addr);
267
/* static unsigned long mem_hash(MEM *a) */
268
static unsigned long mem_hash(const void *a_void)
272
ret=(unsigned long)((const MEM *)a_void)->addr;
274
ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
278
/* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
279
static int app_info_cmp(const void *a_void, const void *b_void)
281
return(((const APP_INFO *)a_void)->thread
282
!= ((const APP_INFO *)b_void)->thread);
285
/* static unsigned long app_info_hash(APP_INFO *a) */
286
static unsigned long app_info_hash(const void *a_void)
290
ret=(unsigned long)((const APP_INFO *)a_void)->thread;
292
ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
296
static APP_INFO *pop_info(void)
299
APP_INFO *ret = NULL;
303
tmp.thread=CRYPTO_thread_id();
304
if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
306
APP_INFO *next=ret->next;
311
lh_insert(amih,(char *)next);
313
#ifdef LEVITTE_DEBUG_MEM
314
if (ret->thread != tmp.thread)
316
fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
317
ret->thread, tmp.thread);
321
if (--(ret->references) <= 0)
333
int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
335
APP_INFO *ami, *amim;
338
if (is_MemCheck_on())
340
MemCheck_off(); /* obtain MALLOC2 lock */
342
if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
349
if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
357
ami->thread=CRYPTO_thread_id();
364
if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
366
#ifdef LEVITTE_DEBUG_MEM
367
if (ami->thread != amim->thread)
369
fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
370
amim->thread, ami->thread);
377
MemCheck_on(); /* release MALLOC2 lock */
383
int CRYPTO_dbg_pop_info(void)
387
if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
389
MemCheck_off(); /* obtain MALLOC2 lock */
391
ret=(pop_info() != NULL);
393
MemCheck_on(); /* release MALLOC2 lock */
398
int CRYPTO_dbg_remove_all_info(void)
402
if (is_MemCheck_on()) /* _must_ be true */
404
MemCheck_off(); /* obtain MALLOC2 lock */
406
while(pop_info() != NULL)
409
MemCheck_on(); /* release MALLOC2 lock */
415
static unsigned long break_order_num=0;
416
void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
422
switch(before_p & 127)
430
if (is_MemCheck_on())
432
MemCheck_off(); /* make sure we hold MALLOC2 lock */
433
if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
436
MemCheck_on(); /* release MALLOC2 lock
437
* if num_disabled drops to 0 */
442
if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
455
if (options & V_CRYPTO_MDEBUG_THREAD)
456
m->thread=CRYPTO_thread_id();
460
if (order == break_order_num)
466
#ifdef LEVITTE_DEBUG_MEM
467
fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
469
(before_p & 128) ? '*' : '+',
472
if (options & V_CRYPTO_MDEBUG_TIME)
477
tmp.thread=CRYPTO_thread_id();
480
&& (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
486
if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
488
/* Not good, but don't sweat it */
489
if (mm->app_info != NULL)
491
mm->app_info->references--;
496
MemCheck_on(); /* release MALLOC2 lock
497
* if num_disabled drops to 0 */
504
void CRYPTO_dbg_free(void *addr, int before_p)
514
if (is_MemCheck_on() && (mh != NULL))
516
MemCheck_off(); /* make sure we hold MALLOC2 lock */
519
mp=(MEM *)lh_delete(mh,(char *)&m);
522
#ifdef LEVITTE_DEBUG_MEM
523
fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
524
mp->order, mp->addr, mp->num);
526
if (mp->app_info != NULL)
527
app_info_free(mp->app_info);
531
MemCheck_on(); /* release MALLOC2 lock
532
* if num_disabled drops to 0 */
540
void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
541
const char *file, int line, int before_p)
545
#ifdef LEVITTE_DEBUG_MEM
546
fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
547
addr1, addr2, num, file, line, before_p);
560
CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
564
if (is_MemCheck_on())
566
MemCheck_off(); /* make sure we hold MALLOC2 lock */
569
mp=(MEM *)lh_delete(mh,(char *)&m);
572
#ifdef LEVITTE_DEBUG_MEM
573
fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
580
lh_insert(mh,(char *)mp);
583
MemCheck_on(); /* release MALLOC2 lock
584
* if num_disabled drops to 0 */
592
typedef struct mem_leak_st
599
static void print_leak(const MEM *m, MEM_LEAK *l)
605
struct tm *lcl = NULL;
608
#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
610
if(m->addr == (char *)l->bio)
613
if (options & V_CRYPTO_MDEBUG_TIME)
615
lcl = localtime(&m->time);
617
BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
618
lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
619
bufp += strlen(bufp);
622
BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
623
m->order,m->file,m->line);
624
bufp += strlen(bufp);
626
if (options & V_CRYPTO_MDEBUG_THREAD)
628
BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread);
629
bufp += strlen(bufp);
632
BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
633
m->num,(unsigned long)m->addr);
634
bufp += strlen(bufp);
636
BIO_puts(l->bio,buf);
653
memset(buf,'>',ami_cnt);
654
BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
655
" thread=%lu, file=%s, line=%d, info=\"",
656
amip->thread, amip->file, amip->line);
658
info_len=strlen(amip->info);
659
if (128 - buf_len - 3 < info_len)
661
memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
666
BUF_strlcpy(buf + buf_len, amip->info,
667
sizeof buf - buf_len);
668
buf_len = strlen(buf);
670
BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
672
BIO_puts(l->bio,buf);
676
while(amip && amip->thread == ti);
678
#ifdef LEVITTE_DEBUG_MEM
681
fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
687
static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
689
void CRYPTO_mem_leaks(BIO *b)
693
if (mh == NULL && amih == NULL)
696
MemCheck_off(); /* obtain MALLOC2 lock */
702
lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
706
BIO_printf(b,"%ld bytes leaked in %d chunks\n",
711
/* Make sure that, if we found no leaks, memory-leak debugging itself
712
* does not introduce memory leaks (which might irritate
713
* external debugging tools).
714
* (When someone enables leak checking, but does not call
715
* this function, we declare it to be their fault.)
717
* XXX This should be in CRYPTO_mem_leaks_cb,
718
* and CRYPTO_mem_leaks should be implemented by
719
* using CRYPTO_mem_leaks_cb.
720
* (Also their should be a variant of lh_doall_arg
721
* that takes a function pointer instead of a void *;
722
* this would obviate the ugly and illegal
723
* void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
724
* Otherwise the code police will come and get us.)
728
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
730
/* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
731
* which uses CRYPTO_is_mem_check_on */
732
old_mh_mode = mh_mode;
733
mh_mode = CRYPTO_MEM_CHECK_OFF;
742
if (lh_num_items(amih) == 0)
749
mh_mode = old_mh_mode;
750
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
752
MemCheck_on(); /* release MALLOC2 lock */
755
#ifndef OPENSSL_NO_FP_API
756
void CRYPTO_mem_leaks_fp(FILE *fp)
760
if (mh == NULL) return;
761
/* Need to turn off memory checking when allocated BIOs ... especially
762
* as we're creating them at a time when we're trying to check we've not
763
* left anything un-free()'d!! */
765
b = BIO_new(BIO_s_file());
768
BIO_set_fp(b,fp,BIO_NOCLOSE);
776
/* FIXME: We really don't allow much to the callback. For example, it has
777
no chance of reaching the info stack for the item it processes. Should
778
it really be this way? -- Richard Levitte */
779
/* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
780
* If this code is restructured, remove the callback type if it is no longer
781
* needed. -- Geoff Thorpe */
782
static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
784
(**cb)(m->order,m->file,m->line,m->num,m->addr);
787
static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
789
void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
791
if (mh == NULL) return;
792
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
793
lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
794
CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
797
void CRYPTO_malloc_debug_init(void)
799
CRYPTO_set_mem_debug_functions(
803
CRYPTO_dbg_set_options,
804
CRYPTO_dbg_get_options);
805
CRYPTO_set_mem_info_functions(
806
CRYPTO_dbg_push_info,
808
CRYPTO_dbg_remove_all_info);
811
char *CRYPTO_strdup(const char *str, const char *file, int line)
813
char *ret = CRYPTO_malloc(strlen(str)+1, file, line);