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.]
62 #include <openssl/crypto.h>
63 #include <openssl/buffer.h>
64 #include <openssl/bio.h>
65 #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)
255 return((const char *)((const MEM *)a_void)->addr
256 - (const char *)((const MEM *)b_void)->addr);
259 /* static unsigned long mem_hash(MEM *a) */
260 static unsigned long mem_hash(const void *a_void)
264 ret=(unsigned long)((const MEM *)a_void)->addr;
266 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
270 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
271 static int app_info_cmp(const void *a_void, const void *b_void)
273 return(((const APP_INFO *)a_void)->thread
274 != ((const APP_INFO *)b_void)->thread);
277 /* static unsigned long app_info_hash(APP_INFO *a) */
278 static unsigned long app_info_hash(const void *a_void)
282 ret=(unsigned long)((const APP_INFO *)a_void)->thread;
284 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
288 static APP_INFO *pop_info(void)
291 APP_INFO *ret = NULL;
295 tmp.thread=CRYPTO_thread_id();
296 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
298 APP_INFO *next=ret->next;
303 lh_insert(amih,(char *)next);
305 #ifdef LEVITTE_DEBUG_MEM
306 if (ret->thread != tmp.thread)
308 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
309 ret->thread, tmp.thread);
313 if (--(ret->references) <= 0)
325 int CRYPTO_push_info_(const char *info, const char *file, int line)
327 APP_INFO *ami, *amim;
330 if (is_MemCheck_on())
332 MemCheck_off(); /* obtain MALLOC2 lock */
334 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
341 if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
349 ami->thread=CRYPTO_thread_id();
356 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
358 #ifdef LEVITTE_DEBUG_MEM
359 if (ami->thread != amim->thread)
361 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
362 amim->thread, ami->thread);
369 MemCheck_on(); /* release MALLOC2 lock */
375 int CRYPTO_pop_info(void)
379 if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
381 MemCheck_off(); /* obtain MALLOC2 lock */
383 ret=(pop_info() != NULL);
385 MemCheck_on(); /* release MALLOC2 lock */
390 int CRYPTO_remove_all_info(void)
394 if (is_MemCheck_on()) /* _must_ be true */
396 MemCheck_off(); /* obtain MALLOC2 lock */
398 while(pop_info() != NULL)
401 MemCheck_on(); /* release MALLOC2 lock */
407 static unsigned long break_order_num=0;
408 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
414 switch(before_p & 127)
422 if (is_MemCheck_on())
424 MemCheck_off(); /* make sure we hold MALLOC2 lock */
425 if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
428 MemCheck_on(); /* release MALLOC2 lock
429 * if num_disabled drops to 0 */
434 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
447 if (options & V_CRYPTO_MDEBUG_THREAD)
448 m->thread=CRYPTO_thread_id();
452 if (order == break_order_num)
458 #ifdef LEVITTE_DEBUG_MEM
459 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
461 (before_p & 128) ? '*' : '+',
464 if (options & V_CRYPTO_MDEBUG_TIME)
469 tmp.thread=CRYPTO_thread_id();
472 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
478 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
480 /* Not good, but don't sweat it */
481 if (mm->app_info != NULL)
483 mm->app_info->references--;
488 MemCheck_on(); /* release MALLOC2 lock
489 * if num_disabled drops to 0 */
496 void CRYPTO_dbg_free(void *addr, int before_p)
506 if (is_MemCheck_on() && (mh != NULL))
508 MemCheck_off(); /* make sure we hold MALLOC2 lock */
511 mp=(MEM *)lh_delete(mh,(char *)&m);
514 #ifdef LEVITTE_DEBUG_MEM
515 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
516 mp->order, mp->addr, mp->num);
518 if (mp->app_info != NULL)
519 app_info_free(mp->app_info);
523 MemCheck_on(); /* release MALLOC2 lock
524 * if num_disabled drops to 0 */
532 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
533 const char *file, int line, int before_p)
537 #ifdef LEVITTE_DEBUG_MEM
538 fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
539 addr1, addr2, num, file, line, before_p);
552 CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
556 if (is_MemCheck_on())
558 MemCheck_off(); /* make sure we hold MALLOC2 lock */
561 mp=(MEM *)lh_delete(mh,(char *)&m);
564 #ifdef LEVITTE_DEBUG_MEM
565 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
572 lh_insert(mh,(char *)mp);
575 MemCheck_on(); /* release MALLOC2 lock
576 * if num_disabled drops to 0 */
584 typedef struct mem_leak_st
591 static void print_leak(const MEM *m, MEM_LEAK *l)
597 struct tm *lcl = NULL;
600 if(m->addr == (char *)l->bio)
603 if (options & V_CRYPTO_MDEBUG_TIME)
605 lcl = localtime(&m->time);
607 sprintf(bufp, "[%02d:%02d:%02d] ",
608 lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
609 bufp += strlen(bufp);
612 sprintf(bufp, "%5lu file=%s, line=%d, ",
613 m->order,m->file,m->line);
614 bufp += strlen(bufp);
616 if (options & V_CRYPTO_MDEBUG_THREAD)
618 sprintf(bufp, "thread=%lu, ", m->thread);
619 bufp += strlen(bufp);
622 sprintf(bufp, "number=%d, address=%08lX\n",
623 m->num,(unsigned long)m->addr);
624 bufp += strlen(bufp);
626 BIO_puts(l->bio,buf);
643 memset(buf,'>',ami_cnt);
644 sprintf(buf + ami_cnt,
645 " thread=%lu, file=%s, line=%d, info=\"",
646 amip->thread, amip->file, amip->line);
648 info_len=strlen(amip->info);
649 if (128 - buf_len - 3 < info_len)
651 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
656 strcpy(buf + buf_len, amip->info);
657 buf_len = strlen(buf);
659 sprintf(buf + buf_len, "\"\n");
661 BIO_puts(l->bio,buf);
665 while(amip && amip->thread == ti);
667 #ifdef LEVITTE_DEBUG_MEM
670 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
676 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
678 void CRYPTO_mem_leaks(BIO *b)
682 if (mh == NULL && amih == NULL)
685 MemCheck_off(); /* obtain MALLOC2 lock */
691 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
695 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
700 /* Make sure that, if we found no leaks, memory-leak debugging itself
701 * does not introduce memory leaks (which might irritate
702 * external debugging tools).
703 * (When someone enables leak checking, but does not call
704 * this function, we declare it to be their fault.)
706 * XXX This should be in CRYPTO_mem_leaks_cb,
707 * and CRYPTO_mem_leaks should be implemented by
708 * using CRYPTO_mem_leaks_cb.
709 * (Also their should be a variant of lh_doall_arg
710 * that takes a function pointer instead of a void *;
711 * this would obviate the ugly and illegal
712 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
713 * Otherwise the code police will come and get us.)
717 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
719 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
720 * which uses CRYPTO_is_mem_check_on */
721 old_mh_mode = mh_mode;
722 mh_mode = CRYPTO_MEM_CHECK_OFF;
731 if (lh_num_items(amih) == 0)
738 mh_mode = old_mh_mode;
739 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
741 MemCheck_on(); /* release MALLOC2 lock */
744 #ifndef OPENSSL_NO_FP_API
745 void CRYPTO_mem_leaks_fp(FILE *fp)
749 if (mh == NULL) return;
750 /* Need to turn off memory checking when allocated BIOs ... especially
751 * as we're creating them at a time when we're trying to check we've not
752 * left anything un-free()'d!! */
754 b = BIO_new(BIO_s_file());
757 BIO_set_fp(b,fp,BIO_NOCLOSE);
765 /* FIXME: We really don't allow much to the callback. For example, it has
766 no chance of reaching the info stack for the item it processes. Should
767 it really be this way? -- Richard Levitte */
768 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
769 * If this code is restructured, remove the callback type if it is no longer
770 * needed. -- Geoff Thorpe */
771 static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
773 (**cb)(m->order,m->file,m->line,m->num,m->addr);
776 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
778 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
780 if (mh == NULL) return;
781 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
782 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
783 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);