2 /* Written by Richard Levitte (richard@levitte.org) for the OpenSSL
5 /* ====================================================================
6 * Copyright (c) 1999 The OpenSSL Project. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in
17 * the documentation and/or other materials provided with the
20 * 3. All advertising materials mentioning features or use of this
21 * software must display the following acknowledgment:
22 * "This product includes software developed by the OpenSSL Project
23 * for use in the OpenSSL Toolkit. (http://www.OpenSSL.org/)"
25 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
26 * endorse or promote products derived from this software without
27 * prior written permission. For written permission, please contact
28 * licensing@OpenSSL.org.
30 * 5. Products derived from this software may not be called "OpenSSL"
31 * nor may "OpenSSL" appear in their names without prior written
32 * permission of the OpenSSL Project.
34 * 6. Redistributions of any form whatsoever must retain the following
36 * "This product includes software developed by the OpenSSL Project
37 * for use in the OpenSSL Toolkit (http://www.OpenSSL.org/)"
39 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
40 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
43 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50 * OF THE POSSIBILITY OF SUCH DAMAGE.
51 * ====================================================================
53 * This product includes cryptographic software written by Eric Young
54 * (eay@cryptsoft.com). This product includes software written by Tim
55 * Hudson (tjh@cryptsoft.com).
62 #include <openssl/crypto.h>
63 #include <openssl/buffer.h>
64 #include <openssl/bio.h>
65 #include <openssl/lhash.h>
68 /* State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
69 * thinks that certain allocations should not be checked (e.g. the data
70 * structures used for memory checking). It is not suitable as an initial
71 * state: the library will unexpectedly enable memory checking when it
72 * executes one of those sections that want to disable checking
75 * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
77 static int mh_mode=CRYPTO_MEM_CHECK_OFF;
78 static unsigned long disabling_thread = 0;
81 static unsigned long order=0;
83 static LHASH *amih=NULL;
85 typedef struct app_mem_info_st
91 struct app_mem_info_st *next;
95 static LHASH *mh=NULL;
103 unsigned long thread;
109 static int options = V_CRYPTO_MDEBUG_TIME | V_CRYPTO_MDEBUG_THREAD;
112 int CRYPTO_mem_ctrl(int mode)
116 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
119 /* for applications: */
120 case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
121 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
122 disabling_thread = 0;
124 case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
126 disabling_thread = 0;
129 /* switch off temporarily (for library-internal use): */
130 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
131 if (mh_mode & CRYPTO_MEM_CHECK_ON)
133 mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE;
134 if (disabling_thread != CRYPTO_thread_id()) /* otherwise we already have the MALLOC2 lock */
136 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
137 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
138 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release it
139 * because we block entry to this function).
140 * Give them a chance, first, and then claim the locks in
141 * appropriate order (long-time lock first).
143 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
144 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
145 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
146 * "case" and "if" branch because MemCheck_start and
147 * MemCheck_stop may never be used while there are multiple
148 * OpenSSL threads. */
149 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
150 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
151 disabling_thread=CRYPTO_thread_id();
155 case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
156 if (mh_mode & CRYPTO_MEM_CHECK_ON)
158 mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
159 if (disabling_thread != 0)
162 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
170 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
174 int CRYPTO_mem_check_on(void)
178 if (mh_mode & CRYPTO_MEM_CHECK_ON)
180 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
182 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
183 && disabling_thread != CRYPTO_thread_id();
185 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
191 void CRYPTO_dbg_set_options(int bits)
196 int CRYPTO_dbg_get_options()
201 static int mem_cmp(MEM *a, MEM *b)
203 return(a->addr - b->addr);
206 static unsigned long mem_hash(MEM *a)
210 ret=(unsigned long)a->addr;
212 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
216 static int app_info_cmp(APP_INFO *a, APP_INFO *b)
218 return(a->thread - b->thread);
221 static unsigned long app_info_hash(APP_INFO *a)
225 ret=(unsigned long)a->thread;
227 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
231 static APP_INFO *remove_info()
234 APP_INFO *ret = NULL;
238 tmp.thread=CRYPTO_thread_id();
239 if ((ret=(APP_INFO *)lh_delete(amih,(char *)&tmp)) != NULL)
241 APP_INFO *next=ret->next;
246 lh_insert(amih,(char *)next);
249 if (ret->thread != tmp.thread)
251 fprintf(stderr, "remove_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
252 ret->thread, tmp.thread);
256 if (--(ret->references) <= 0)
268 int CRYPTO_add_info(const char *file, int line, const char *info)
270 APP_INFO *ami, *amim;
273 if (is_MemCheck_on())
277 if ((ami = (APP_INFO *)Malloc(sizeof(APP_INFO))) == NULL)
284 if ((amih=lh_new(app_info_hash,app_info_cmp)) == NULL)
292 ami->thread=CRYPTO_thread_id();
299 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
302 if (ami->thread != amim->thread)
304 fprintf(stderr, "CRYPTO_add_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
305 amim->thread, ami->thread);
318 int CRYPTO_remove_info(void)
322 if (is_MemCheck_on())
326 ret=(remove_info() != NULL);
333 int CRYPTO_remove_all_info(void)
337 if (is_MemCheck_on())
341 while(remove_info() != NULL)
350 static unsigned long break_order_num=0;
351 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
357 switch(before_p & 127)
365 if (is_MemCheck_on())
368 if ((m=(MEM *)Malloc(sizeof(MEM))) == NULL)
376 if ((mh=lh_new(mem_hash,mem_cmp)) == NULL)
389 if (options & V_CRYPTO_MDEBUG_THREAD)
390 m->thread=CRYPTO_thread_id();
394 if (order == break_order_num)
401 fprintf(stderr, "LEVITTE_DEBUG: [%5d] %c 0x%p (%d)\n",
403 (before_p & 128) ? '*' : '+',
406 if (options & V_CRYPTO_MDEBUG_TIME)
411 tmp.thread=CRYPTO_thread_id();
414 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
420 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
422 /* Not good, but don't sweat it */
423 if (mm->app_info != NULL)
425 mm->app_info->references--;
437 void CRYPTO_dbg_free(void *addr, int before_p)
447 if (is_MemCheck_on() && (mh != NULL))
452 mp=(MEM *)lh_delete(mh,(char *)&m);
456 fprintf(stderr, "LEVITTE_DEBUG: [%5d] - 0x%p (%d)\n",
457 mp->order, mp->addr, mp->num);
459 if (mp->app_info != NULL)
461 mp->app_info->references--;
474 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
475 const char *file, int line, int before_p)
480 fprintf(stderr, "LEVITTE_DEBUG: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
481 addr1, addr2, num, file, line, before_p);
494 CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
498 if (is_MemCheck_on())
503 mp=(MEM *)lh_delete(mh,(char *)&m);
507 fprintf(stderr, "LEVITTE_DEBUG: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
514 lh_insert(mh,(char *)mp);
525 typedef struct mem_leak_st
532 static void print_leak(MEM *m, MEM_LEAK *l)
538 struct tm *lcl = NULL;
541 if(m->addr == (char *)l->bio)
544 if (options & V_CRYPTO_MDEBUG_TIME)
546 lcl = localtime(&m->time);
548 sprintf(bufp, "[%02d:%02d:%02d] ",
549 lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
550 bufp += strlen(bufp);
553 sprintf(bufp, "%5lu file=%s, line=%d, ",
554 m->order,m->file,m->line);
555 bufp += strlen(bufp);
557 if (options & V_CRYPTO_MDEBUG_THREAD)
559 sprintf(bufp, "thread=%lu, ", m->thread);
560 bufp += strlen(bufp);
563 sprintf(bufp, "number=%d, address=%08lX\n",
564 m->num,(unsigned long)m->addr);
565 bufp += strlen(bufp);
567 BIO_puts(l->bio,buf);
576 while(amip && amip->thread == ti)
582 memset(buf,'>',ami_cnt);
583 sprintf(buf + ami_cnt,
584 "thread=%lu, file=%s, line=%d, info=\"",
585 amip->thread, amip->file, amip->line);
587 info_len=strlen(amip->info);
588 if (128 - buf_len - 3 < info_len)
590 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
595 strcpy(buf + buf_len, amip->info);
596 buf_len = strlen(buf);
598 sprintf(buf + buf_len, "\"\n");
600 BIO_puts(l->bio,buf);
607 fprintf(stderr, "Thread switch detected i backtrace!!!!\n");
613 void CRYPTO_mem_leaks(BIO *b)
618 if (mh == NULL) return;
622 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
623 lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml);
624 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
627 sprintf(buf,"%ld bytes leaked in %d chunks\n",
634 lh_node_stats_bio(mh,b);
635 lh_node_usage_stats_bio(mh,b);
639 static void (*mem_cb)()=NULL;
641 static void cb_leak(MEM *m, char *cb)
643 void (*mem_callback)()=(void (*)())cb;
644 mem_callback(m->order,m->file,m->line,m->num,m->addr);
647 void CRYPTO_mem_leaks_cb(void (*cb)())
649 if (mh == NULL) return;
650 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
652 lh_doall_arg(mh,(void (*)())cb_leak,(char *)mem_cb);
654 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
658 void CRYPTO_mem_leaks_fp(FILE *fp)
662 if (mh == NULL) return;
663 if ((b=BIO_new(BIO_s_file())) == NULL)
665 BIO_set_fp(b,fp,BIO_NOCLOSE);