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) */
87 typedef struct app_mem_info_st
88 /* For application-defined information (static C-string `info')
89 * to be displayed in memory leak list.
90 * Each thread has its own stack. For applications, there is
91 * CRYPTO_push_info("...") to push an entry,
92 * CRYPTO_pop_info() to pop an entry,
93 * CRYPTO_remove_all_info() to pop all entries.
100 struct app_mem_info_st *next; /* tail of thread's stack */
104 static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
105 * that are at the top of their thread's stack
106 * (with `thread' as key) */
108 typedef struct mem_st
109 /* memory-block description */
115 unsigned long thread;
121 static long options = /* extra information to be recorded */
122 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
123 V_CRYPTO_MDEBUG_TIME |
125 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
126 V_CRYPTO_MDEBUG_THREAD |
131 static unsigned long disabling_thread = 0;
133 int CRYPTO_mem_ctrl(int mode)
137 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
140 /* for applications: */
141 case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
142 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
143 disabling_thread = 0;
145 case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
147 disabling_thread = 0;
150 /* switch off temporarily (for library-internal use): */
151 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
152 if (mh_mode & CRYPTO_MEM_CHECK_ON)
154 mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE;
155 if (disabling_thread != CRYPTO_thread_id()) /* otherwise we already have the MALLOC2 lock */
157 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
158 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
159 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
160 * it because we block entry to this function).
161 * Give them a chance, first, and then claim the locks in
162 * appropriate order (long-time lock first).
164 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
165 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
166 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
167 * "case" and "if" branch because MemCheck_start and
168 * MemCheck_stop may never be used while there are multiple
169 * OpenSSL threads. */
170 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
171 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
172 disabling_thread=CRYPTO_thread_id();
176 case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
177 if (mh_mode & CRYPTO_MEM_CHECK_ON)
179 mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
180 if (disabling_thread != 0)
183 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
191 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
195 int CRYPTO_is_mem_check_on(void)
199 if (mh_mode & CRYPTO_MEM_CHECK_ON)
201 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
203 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
204 && disabling_thread != CRYPTO_thread_id();
206 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
212 void CRYPTO_dbg_set_options(long bits)
217 long CRYPTO_dbg_get_options(void)
222 /* static int mem_cmp(MEM *a, MEM *b) */
223 static int mem_cmp(const void *a_void, const void *b_void)
225 return((const char *)((MEM *)a_void)->addr
226 - (const char *)((MEM *)b_void)->addr);
229 /* static unsigned long mem_hash(MEM *a) */
230 static unsigned long mem_hash(const void *a_void)
234 ret=(unsigned long)((const MEM *)a_void)->addr;
236 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
240 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
241 static int app_info_cmp(const void *a_void, const void *b_void)
243 return(((const APP_INFO *)a_void)->thread
244 != ((const APP_INFO *)b_void)->thread);
247 /* static unsigned long app_info_hash(APP_INFO *a) */
248 static unsigned long app_info_hash(const void *a_void)
252 ret=(unsigned long)((const APP_INFO *)a_void)->thread;
254 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
258 static APP_INFO *pop_info(void)
261 APP_INFO *ret = NULL;
265 tmp.thread=CRYPTO_thread_id();
266 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
268 APP_INFO *next=ret->next;
273 lh_insert(amih,(char *)next);
275 #ifdef LEVITTE_DEBUG_MEM
276 if (ret->thread != tmp.thread)
278 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
279 ret->thread, tmp.thread);
283 if (--(ret->references) <= 0)
295 int CRYPTO_push_info_(const char *info, const char *file, int line)
297 APP_INFO *ami, *amim;
300 if (is_MemCheck_on())
302 MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */
304 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
311 if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
319 ami->thread=CRYPTO_thread_id();
326 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
328 #ifdef LEVITTE_DEBUG_MEM
329 if (ami->thread != amim->thread)
331 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
332 amim->thread, ami->thread);
339 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
345 int CRYPTO_pop_info(void)
349 if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
351 MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */
353 ret=(pop_info() != NULL);
355 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
360 int CRYPTO_remove_all_info(void)
364 if (is_MemCheck_on()) /* _must_ be true */
366 MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */
368 while(pop_info() != NULL)
371 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
377 static unsigned long break_order_num=0;
378 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
384 switch(before_p & 127)
392 if (is_MemCheck_on())
394 MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */
395 if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
398 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
403 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
416 if (options & V_CRYPTO_MDEBUG_THREAD)
417 m->thread=CRYPTO_thread_id();
421 if (order == break_order_num)
427 #ifdef LEVITTE_DEBUG_MEM
428 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
430 (before_p & 128) ? '*' : '+',
433 if (options & V_CRYPTO_MDEBUG_TIME)
438 tmp.thread=CRYPTO_thread_id();
441 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
447 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
449 /* Not good, but don't sweat it */
450 if (mm->app_info != NULL)
452 mm->app_info->references--;
457 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
464 void CRYPTO_dbg_free(void *addr, int before_p)
474 if (is_MemCheck_on() && (mh != NULL))
479 mp=(MEM *)lh_delete(mh,(char *)&m);
482 #ifdef LEVITTE_DEBUG_MEM
483 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
484 mp->order, mp->addr, mp->num);
486 if (mp->app_info != NULL)
488 mp->app_info->references--;
493 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
501 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
502 const char *file, int line, int before_p)
506 #ifdef LEVITTE_DEBUG_MEM
507 fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
508 addr1, addr2, num, file, line, before_p);
521 CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
525 if (is_MemCheck_on())
527 MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */
530 mp=(MEM *)lh_delete(mh,(char *)&m);
533 #ifdef LEVITTE_DEBUG_MEM
534 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
541 lh_insert(mh,(char *)mp);
544 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
552 typedef struct mem_leak_st
559 static void print_leak(MEM *m, MEM_LEAK *l)
565 struct tm *lcl = NULL;
568 if(m->addr == (char *)l->bio)
571 if (options & V_CRYPTO_MDEBUG_TIME)
573 lcl = localtime(&m->time);
575 sprintf(bufp, "[%02d:%02d:%02d] ",
576 lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
577 bufp += strlen(bufp);
580 sprintf(bufp, "%5lu file=%s, line=%d, ",
581 m->order,m->file,m->line);
582 bufp += strlen(bufp);
584 if (options & V_CRYPTO_MDEBUG_THREAD)
586 sprintf(bufp, "thread=%lu, ", m->thread);
587 bufp += strlen(bufp);
590 sprintf(bufp, "number=%d, address=%08lX\n",
591 m->num,(unsigned long)m->addr);
592 bufp += strlen(bufp);
594 BIO_puts(l->bio,buf);
611 memset(buf,'>',ami_cnt);
612 sprintf(buf + ami_cnt,
613 " thread=%lu, file=%s, line=%d, info=\"",
614 amip->thread, amip->file, amip->line);
616 info_len=strlen(amip->info);
617 if (128 - buf_len - 3 < info_len)
619 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
624 strcpy(buf + buf_len, amip->info);
625 buf_len = strlen(buf);
627 sprintf(buf + buf_len, "\"\n");
629 BIO_puts(l->bio,buf);
633 while(amip && amip->thread == ti);
635 #ifdef LEVITTE_DEBUG_MEM
638 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
644 void CRYPTO_mem_leaks(BIO *b)
649 if (mh == NULL && amih == NULL)
654 MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */
656 lh_doall_arg(mh, (LHASH_DOALL_ARG_FN_TYPE)print_leak,
660 sprintf(buf,"%ld bytes leaked in %d chunks\n",
666 /* Make sure that, if we found no leaks, memory-leak debugging itself
667 * does not introduce memory leaks (which might irritate
668 * external debugging tools).
669 * (When someone enables leak checking, but does not call
670 * this function, we declare it to be their fault.)
672 * XXX This should be in CRYPTO_mem_leaks_cb,
673 * and CRYPTO_mem_leaks should be implemented by
674 * using CRYPTO_mem_leaks_cb.
675 * (Also their should be a variant of lh_doall_arg
676 * that takes a function pointer instead of a void *;
677 * this would obviate the ugly and illegal
678 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
679 * Otherwise the code police will come and get us.)
683 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
685 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
686 * which uses CRYPTO_is_mem_check_on */
687 old_mh_mode = mh_mode;
688 mh_mode = CRYPTO_MEM_CHECK_OFF;
697 if (lh_num_items(amih) == 0)
704 mh_mode = old_mh_mode;
705 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
707 MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */
711 lh_node_stats_bio(mh,b);
712 lh_node_usage_stats_bio(mh,b);
717 void CRYPTO_mem_leaks_fp(FILE *fp)
721 if (mh == NULL) return;
722 if ((b=BIO_new(BIO_s_file())) == NULL)
724 BIO_set_fp(b,fp,BIO_NOCLOSE);
732 /* FIXME: We really don't allow much to the callback. For example, it has
733 no chance of reaching the info stack for the item it processes. Should
734 it really be this way? -- Richard Levitte */
735 static void cb_leak(MEM *m,
736 void (**cb)(unsigned long, const char *, int, int, void *))
738 (**cb)(m->order,m->file,m->line,m->num,m->addr);
741 void CRYPTO_mem_leaks_cb(void (*cb)(unsigned long, const char *, int, int, void *))
743 if (mh == NULL) return;
744 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
745 lh_doall_arg(mh, (LHASH_DOALL_ARG_FN_TYPE)cb_leak,(void *)&cb);
746 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);