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
90 * For application-defined information (static C-string `info')
91 * to be displayed in memory leak list.
92 * Each thread has its own stack. For applications, there is
93 * CRYPTO_push_info("...") to push an entry,
94 * CRYPTO_pop_info() to pop an entry,
95 * CRYPTO_remove_all_info() to pop all entries.
102 struct app_mem_info_st *next; /* tail of thread's stack */
106 static void app_info_free(APP_INFO *);
108 static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
109 * that are at the top of their thread's stack
110 * (with `thread' as key);
111 * access requires MALLOC2 lock */
113 typedef struct mem_st
114 /* memory-block description */
120 unsigned long thread;
126 static long options = /* extra information to be recorded */
127 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
128 V_CRYPTO_MDEBUG_TIME |
130 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
131 V_CRYPTO_MDEBUG_THREAD |
136 static unsigned int num_disable = 0; /* num_disable > 0
138 * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
140 static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0.
141 * CRYPTO_LOCK_MALLOC2 is locked
142 * exactly in this case (by the
143 * thread named in disabling_thread).
146 static void app_info_free(APP_INFO *inf)
148 if (--(inf->references) <= 0)
150 if (inf->next != NULL)
152 app_info_free(inf->next);
158 int CRYPTO_mem_ctrl(int mode)
162 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
165 /* for applications (not to be called while multiple threads
166 * use the library): */
167 case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
168 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
171 case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
173 num_disable = 0; /* should be true *before* MemCheck_stop is
174 used, or there'll be a lot of confusion */
177 /* switch off temporarily (for library-internal use): */
178 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
179 if (mh_mode & CRYPTO_MEM_CHECK_ON)
181 /* otherwise we already have the MALLOC2 lock */
182 if (!num_disable || (disabling_thread != CRYPTO_thread_id()))
184 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
185 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
186 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
187 * it because we block entry to this function).
188 * Give them a chance, first, and then claim the locks in
189 * appropriate order (long-time lock first).
191 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
192 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
193 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
194 * "case" and "if" branch because MemCheck_start and
195 * MemCheck_stop may never be used while there are multiple
196 * OpenSSL threads. */
197 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
198 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
199 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
200 disabling_thread=CRYPTO_thread_id();
205 case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
206 if (mh_mode & CRYPTO_MEM_CHECK_ON)
208 if (num_disable) /* always true, or something is going wrong */
211 if (num_disable == 0)
213 mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
214 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
223 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
227 int CRYPTO_is_mem_check_on(void)
231 if (mh_mode & CRYPTO_MEM_CHECK_ON)
233 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
235 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
236 || (disabling_thread != CRYPTO_thread_id());
238 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
244 void CRYPTO_dbg_set_options(long bits)
249 long CRYPTO_dbg_get_options(void)
254 /* static int mem_cmp(MEM *a, MEM *b) */
255 static int mem_cmp(const void *a_void, const void *b_void)
258 const char *a=(const char *)((const MEM *)a_void)->addr,
259 *b=(const char *)((const MEM *)b_void)->addr;
261 else if (a>b) return 1;
264 return((const char *)((const MEM *)a_void)->addr
265 - (const char *)((const MEM *)b_void)->addr);
269 /* static unsigned long mem_hash(MEM *a) */
270 static unsigned long mem_hash(const void *a_void)
274 ret=(unsigned long)((const MEM *)a_void)->addr;
276 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
280 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
281 static int app_info_cmp(const void *a_void, const void *b_void)
283 return(((const APP_INFO *)a_void)->thread
284 != ((const APP_INFO *)b_void)->thread);
287 /* static unsigned long app_info_hash(APP_INFO *a) */
288 static unsigned long app_info_hash(const void *a_void)
292 ret=(unsigned long)((const APP_INFO *)a_void)->thread;
294 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
298 static APP_INFO *pop_info(void)
301 APP_INFO *ret = NULL;
305 tmp.thread=CRYPTO_thread_id();
306 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
308 APP_INFO *next=ret->next;
313 lh_insert(amih,(char *)next);
315 #ifdef LEVITTE_DEBUG_MEM
316 if (ret->thread != tmp.thread)
318 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
319 ret->thread, tmp.thread);
323 if (--(ret->references) <= 0)
335 int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
337 APP_INFO *ami, *amim;
340 if (is_MemCheck_on())
342 MemCheck_off(); /* obtain MALLOC2 lock */
344 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
351 if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
359 ami->thread=CRYPTO_thread_id();
366 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
368 #ifdef LEVITTE_DEBUG_MEM
369 if (ami->thread != amim->thread)
371 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
372 amim->thread, ami->thread);
379 MemCheck_on(); /* release MALLOC2 lock */
385 int CRYPTO_dbg_pop_info(void)
389 if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
391 MemCheck_off(); /* obtain MALLOC2 lock */
393 ret=(pop_info() != NULL);
395 MemCheck_on(); /* release MALLOC2 lock */
400 int CRYPTO_dbg_remove_all_info(void)
404 if (is_MemCheck_on()) /* _must_ be true */
406 MemCheck_off(); /* obtain MALLOC2 lock */
408 while(pop_info() != NULL)
411 MemCheck_on(); /* release MALLOC2 lock */
417 static unsigned long break_order_num=0;
418 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
424 switch(before_p & 127)
432 if (is_MemCheck_on())
434 MemCheck_off(); /* make sure we hold MALLOC2 lock */
435 if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
438 MemCheck_on(); /* release MALLOC2 lock
439 * if num_disabled drops to 0 */
444 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
457 if (options & V_CRYPTO_MDEBUG_THREAD)
458 m->thread=CRYPTO_thread_id();
462 if (order == break_order_num)
468 #ifdef LEVITTE_DEBUG_MEM
469 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
471 (before_p & 128) ? '*' : '+',
474 if (options & V_CRYPTO_MDEBUG_TIME)
479 tmp.thread=CRYPTO_thread_id();
482 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
488 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
490 /* Not good, but don't sweat it */
491 if (mm->app_info != NULL)
493 mm->app_info->references--;
498 MemCheck_on(); /* release MALLOC2 lock
499 * if num_disabled drops to 0 */
506 void CRYPTO_dbg_free(void *addr, int before_p)
516 if (is_MemCheck_on() && (mh != NULL))
518 MemCheck_off(); /* make sure we hold MALLOC2 lock */
521 mp=(MEM *)lh_delete(mh,(char *)&m);
524 #ifdef LEVITTE_DEBUG_MEM
525 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
526 mp->order, mp->addr, mp->num);
528 if (mp->app_info != NULL)
529 app_info_free(mp->app_info);
533 MemCheck_on(); /* release MALLOC2 lock
534 * if num_disabled drops to 0 */
542 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
543 const char *file, int line, int before_p)
547 #ifdef LEVITTE_DEBUG_MEM
548 fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
549 addr1, addr2, num, file, line, before_p);
562 CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
566 if (is_MemCheck_on())
568 MemCheck_off(); /* make sure we hold MALLOC2 lock */
571 mp=(MEM *)lh_delete(mh,(char *)&m);
574 #ifdef LEVITTE_DEBUG_MEM
575 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
582 lh_insert(mh,(char *)mp);
585 MemCheck_on(); /* release MALLOC2 lock
586 * if num_disabled drops to 0 */
594 typedef struct mem_leak_st
601 static void print_leak(const MEM *m, MEM_LEAK *l)
607 struct tm *lcl = NULL;
610 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
612 if(m->addr == (char *)l->bio)
615 if (options & V_CRYPTO_MDEBUG_TIME)
617 lcl = localtime(&m->time);
619 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
620 lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
621 bufp += strlen(bufp);
624 BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
625 m->order,m->file,m->line);
626 bufp += strlen(bufp);
628 if (options & V_CRYPTO_MDEBUG_THREAD)
630 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread);
631 bufp += strlen(bufp);
634 BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
635 m->num,(unsigned long)m->addr);
636 bufp += strlen(bufp);
638 BIO_puts(l->bio,buf);
655 memset(buf,'>',ami_cnt);
656 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
657 " thread=%lu, file=%s, line=%d, info=\"",
658 amip->thread, amip->file, amip->line);
660 info_len=strlen(amip->info);
661 if (128 - buf_len - 3 < info_len)
663 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
668 BUF_strlcpy(buf + buf_len, amip->info,
669 sizeof buf - buf_len);
670 buf_len = strlen(buf);
672 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
674 BIO_puts(l->bio,buf);
678 while(amip && amip->thread == ti);
680 #ifdef LEVITTE_DEBUG_MEM
683 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
689 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
691 void CRYPTO_mem_leaks(BIO *b)
695 if (mh == NULL && amih == NULL)
698 MemCheck_off(); /* obtain MALLOC2 lock */
704 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
708 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
713 /* Make sure that, if we found no leaks, memory-leak debugging itself
714 * does not introduce memory leaks (which might irritate
715 * external debugging tools).
716 * (When someone enables leak checking, but does not call
717 * this function, we declare it to be their fault.)
719 * XXX This should be in CRYPTO_mem_leaks_cb,
720 * and CRYPTO_mem_leaks should be implemented by
721 * using CRYPTO_mem_leaks_cb.
722 * (Also their should be a variant of lh_doall_arg
723 * that takes a function pointer instead of a void *;
724 * this would obviate the ugly and illegal
725 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
726 * Otherwise the code police will come and get us.)
730 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
732 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
733 * which uses CRYPTO_is_mem_check_on */
734 old_mh_mode = mh_mode;
735 mh_mode = CRYPTO_MEM_CHECK_OFF;
744 if (lh_num_items(amih) == 0)
751 mh_mode = old_mh_mode;
752 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
754 MemCheck_on(); /* release MALLOC2 lock */
757 #ifndef OPENSSL_NO_FP_API
758 void CRYPTO_mem_leaks_fp(FILE *fp)
762 if (mh == NULL) return;
763 /* Need to turn off memory checking when allocated BIOs ... especially
764 * as we're creating them at a time when we're trying to check we've not
765 * left anything un-free()'d!! */
767 b = BIO_new(BIO_s_file());
770 BIO_set_fp(b,fp,BIO_NOCLOSE);
778 /* FIXME: We really don't allow much to the callback. For example, it has
779 no chance of reaching the info stack for the item it processes. Should
780 it really be this way? -- Richard Levitte */
781 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
782 * If this code is restructured, remove the callback type if it is no longer
783 * needed. -- Geoff Thorpe */
784 static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
786 (**cb)(m->order,m->file,m->line,m->num,m->addr);
789 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
791 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
793 if (mh == NULL) return;
794 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
795 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
796 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
799 void CRYPTO_malloc_debug_init(void)
801 CRYPTO_set_mem_debug_functions(
805 CRYPTO_dbg_set_options,
806 CRYPTO_dbg_get_options);
807 CRYPTO_set_mem_info_functions(
808 CRYPTO_dbg_push_info,
810 CRYPTO_dbg_remove_all_info);
813 char *CRYPTO_strdup(const char *str, const char *file, int line)
815 char *ret = CRYPTO_malloc(strlen(str)+1, file, line);