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.]
58 /* ====================================================================
59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
61 * Redistribution and use in source and binary forms, with or without
62 * modification, are permitted provided that the following conditions
65 * 1. Redistributions of source code must retain the above copyright
66 * notice, this list of conditions and the following disclaimer.
68 * 2. Redistributions in binary form must reproduce the above copyright
69 * notice, this list of conditions and the following disclaimer in
70 * the documentation and/or other materials provided with the
73 * 3. All advertising materials mentioning features or use of this
74 * software must display the following acknowledgment:
75 * "This product includes software developed by the OpenSSL Project
76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 * endorse or promote products derived from this software without
80 * prior written permission. For written permission, please contact
81 * openssl-core@openssl.org.
83 * 5. Products derived from this software may not be called "OpenSSL"
84 * nor may "OpenSSL" appear in their names without prior written
85 * permission of the OpenSSL Project.
87 * 6. Redistributions of any form whatsoever must retain the following
89 * "This product includes software developed by the OpenSSL Project
90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 * ====================================================================
106 * This product includes cryptographic software written by Eric Young
107 * (eay@cryptsoft.com). This product includes software written by Tim
108 * Hudson (tjh@cryptsoft.com).
115 #include "cryptlib.h"
116 #include <openssl/crypto.h>
117 #include <openssl/buffer.h>
118 #include <openssl/bio.h>
119 #include <openssl/lhash.h>
121 static int mh_mode=CRYPTO_MEM_CHECK_OFF;
122 /* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
123 * when the application asks for it (usually after library initialisation
124 * for which no book-keeping is desired).
126 * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
127 * thinks that certain allocations should not be checked (e.g. the data
128 * structures used for memory checking). It is not suitable as an initial
129 * state: the library will unexpectedly enable memory checking when it
130 * executes one of those sections that want to disable checking
133 * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
136 static unsigned long order = 0; /* number of memory requests */
137 static LHASH *mh=NULL; /* hash-table of memory requests (address as key);
138 * access requires MALLOC2 lock */
141 typedef struct app_mem_info_st
142 /* For application-defined information (static C-string `info')
143 * to be displayed in memory leak list.
144 * Each thread has its own stack. For applications, there is
145 * CRYPTO_push_info("...") to push an entry,
146 * CRYPTO_pop_info() to pop an entry,
147 * CRYPTO_remove_all_info() to pop all entries.
150 CRYPTO_THREADID threadid;
154 struct app_mem_info_st *next; /* tail of thread's stack */
158 static void app_info_free(APP_INFO *);
160 static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's
161 * that are at the top of their thread's stack
162 * (with `thread' as key);
163 * access requires MALLOC2 lock */
165 typedef struct mem_st
166 /* memory-block description */
172 CRYPTO_THREADID threadid;
178 static long options = /* extra information to be recorded */
179 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
180 V_CRYPTO_MDEBUG_TIME |
182 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
183 V_CRYPTO_MDEBUG_THREAD |
188 static unsigned int num_disable = 0; /* num_disable > 0
190 * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
193 /* Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this
194 * case (by the thread named in disabling_threadid). */
195 static CRYPTO_THREADID disabling_threadid;
197 static void app_info_free(APP_INFO *inf)
199 if (--(inf->references) <= 0)
201 if (inf->next != NULL)
203 app_info_free(inf->next);
209 int CRYPTO_mem_ctrl(int mode)
213 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
216 /* for applications (not to be called while multiple threads
217 * use the library): */
218 case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
219 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
222 case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
224 num_disable = 0; /* should be true *before* MemCheck_stop is used,
225 or there'll be a lot of confusion */
228 /* switch off temporarily (for library-internal use): */
229 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
230 if (mh_mode & CRYPTO_MEM_CHECK_ON)
233 CRYPTO_THREADID_set(&tid);
234 if (!num_disable || CRYPTO_THREADID_cmp(&tid,
235 &disabling_threadid))
237 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
238 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
239 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
240 * it because we block entry to this function).
241 * Give them a chance, first, and then claim the locks in
242 * appropriate order (long-time lock first).
244 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
245 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
246 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
247 * "case" and "if" branch because MemCheck_start and
248 * MemCheck_stop may never be used while there are multiple
249 * OpenSSL threads. */
250 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
251 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
252 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
253 CRYPTO_THREADID_set(&disabling_threadid);
258 case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
259 if (mh_mode & CRYPTO_MEM_CHECK_ON)
261 if (num_disable) /* always true, or something is going wrong */
264 if (num_disable == 0)
266 mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
267 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
276 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
280 int CRYPTO_is_mem_check_on(void)
284 if (mh_mode & CRYPTO_MEM_CHECK_ON)
287 CRYPTO_THREADID_set(&tid);
288 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
290 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) ||
291 CRYPTO_THREADID_cmp(&tid, &disabling_threadid);
293 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
299 void CRYPTO_dbg_set_options(long bits)
304 long CRYPTO_dbg_get_options(void)
309 /* static int mem_cmp(MEM *a, MEM *b) */
310 static int mem_cmp(const void *a_void, const void *b_void)
313 const char *a=(const char *)((const MEM *)a_void)->addr,
314 *b=(const char *)((const MEM *)b_void)->addr;
316 else if (a>b) return 1;
319 return((const char *)((const MEM *)a_void)->addr
320 - (const char *)((const MEM *)b_void)->addr);
324 /* static unsigned long mem_hash(MEM *a) */
325 static unsigned long mem_hash(const void *a_void)
329 ret=(unsigned long)((const MEM *)a_void)->addr;
331 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
335 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
336 static int app_info_cmp(const void *a_void, const void *b_void)
338 return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
339 &((const APP_INFO *)b_void)->threadid);
342 /* static unsigned long app_info_hash(APP_INFO *a) */
343 static unsigned long app_info_hash(const void *a_void)
346 ret = CRYPTO_THREADID_hash(&((const APP_INFO *)a_void)->threadid);
347 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
351 static APP_INFO *pop_info(void)
354 APP_INFO *ret = NULL;
358 CRYPTO_THREADID_set(&tmp.threadid);
359 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
361 APP_INFO *next=ret->next;
366 lh_insert(amih,(char *)next);
368 #ifdef LEVITTE_DEBUG_MEM
369 if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
371 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
372 CRYPTO_THREADID_hash(&ret->threadid),
373 CRYPTO_THREADID_hash(&tmp.threadid));
377 if (--(ret->references) <= 0)
389 int CRYPTO_push_info_(const char *info, const char *file, int line)
391 APP_INFO *ami, *amim;
394 if (is_MemCheck_on())
396 MemCheck_off(); /* obtain MALLOC2 lock */
398 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
405 if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
413 CRYPTO_THREADID_set(&ami->threadid);
420 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
422 #ifdef LEVITTE_DEBUG_MEM
423 if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
425 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
426 CRYPTO_THREADID_hash(&amim->threadid),
427 CRYPTO_THREADID_hash(&ami->threadid));
434 MemCheck_on(); /* release MALLOC2 lock */
440 int CRYPTO_pop_info(void)
444 if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
446 MemCheck_off(); /* obtain MALLOC2 lock */
448 ret=(pop_info() != NULL);
450 MemCheck_on(); /* release MALLOC2 lock */
455 int CRYPTO_remove_all_info(void)
459 if (is_MemCheck_on()) /* _must_ be true */
461 MemCheck_off(); /* obtain MALLOC2 lock */
463 while(pop_info() != NULL)
466 MemCheck_on(); /* release MALLOC2 lock */
472 static unsigned long break_order_num=0;
473 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
479 switch(before_p & 127)
487 if (is_MemCheck_on())
489 MemCheck_off(); /* make sure we hold MALLOC2 lock */
490 if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
493 MemCheck_on(); /* release MALLOC2 lock
494 * if num_disabled drops to 0 */
499 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
512 CRYPTO_THREADID_set(&m->threadid);
514 if (order == break_order_num)
520 #ifdef LEVITTE_DEBUG_MEM
521 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
523 (before_p & 128) ? '*' : '+',
526 if (options & V_CRYPTO_MDEBUG_TIME)
531 CRYPTO_THREADID_set(&m->threadid);
534 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
540 if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
542 /* Not good, but don't sweat it */
543 if (mm->app_info != NULL)
545 mm->app_info->references--;
550 MemCheck_on(); /* release MALLOC2 lock
551 * if num_disabled drops to 0 */
558 void CRYPTO_dbg_free(void *addr, int before_p)
568 if (is_MemCheck_on() && (mh != NULL))
570 MemCheck_off(); /* make sure we hold MALLOC2 lock */
573 mp=(MEM *)lh_delete(mh,(char *)&m);
576 #ifdef LEVITTE_DEBUG_MEM
577 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
578 mp->order, mp->addr, mp->num);
580 if (mp->app_info != NULL)
581 app_info_free(mp->app_info);
585 MemCheck_on(); /* release MALLOC2 lock
586 * if num_disabled drops to 0 */
594 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
595 const char *file, int line, int before_p)
599 #ifdef LEVITTE_DEBUG_MEM
600 fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
601 addr1, addr2, num, file, line, before_p);
614 CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
618 if (is_MemCheck_on())
620 MemCheck_off(); /* make sure we hold MALLOC2 lock */
623 mp=(MEM *)lh_delete(mh,(char *)&m);
626 #ifdef LEVITTE_DEBUG_MEM
627 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
634 lh_insert(mh,(char *)mp);
637 MemCheck_on(); /* release MALLOC2 lock
638 * if num_disabled drops to 0 */
646 typedef struct mem_leak_st
653 static void print_leak(const MEM *m, MEM_LEAK *l)
659 struct tm *lcl = NULL;
662 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
664 if(m->addr == (char *)l->bio)
667 if (options & V_CRYPTO_MDEBUG_TIME)
669 lcl = localtime(&m->time);
671 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
672 lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
673 bufp += strlen(bufp);
676 BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
677 m->order,m->file,m->line);
678 bufp += strlen(bufp);
680 if (options & V_CRYPTO_MDEBUG_THREAD)
682 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
683 CRYPTO_THREADID_hash(&m->threadid));
684 bufp += strlen(bufp);
687 BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
688 m->num,(unsigned long)m->addr);
689 bufp += strlen(bufp);
691 BIO_puts(l->bio,buf);
700 CRYPTO_THREADID_set(&tid);
708 memset(buf,'>',ami_cnt);
709 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
710 " thread=%lu, file=%s, line=%d, info=\"",
711 CRYPTO_THREADID_hash(&amip->threadid), amip->file, amip->line);
713 info_len=strlen(amip->info);
714 if (128 - buf_len - 3 < info_len)
716 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
721 BUF_strlcpy(buf + buf_len, amip->info,
722 sizeof buf - buf_len);
723 buf_len = strlen(buf);
725 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
727 BIO_puts(l->bio,buf);
731 while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &tid));
733 #ifdef LEVITTE_DEBUG_MEM
736 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
742 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
744 void CRYPTO_mem_leaks(BIO *b)
748 if (mh == NULL && amih == NULL)
751 MemCheck_off(); /* obtain MALLOC2 lock */
757 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
761 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
766 /* Make sure that, if we found no leaks, memory-leak debugging itself
767 * does not introduce memory leaks (which might irritate
768 * external debugging tools).
769 * (When someone enables leak checking, but does not call
770 * this function, we declare it to be their fault.)
772 * XXX This should be in CRYPTO_mem_leaks_cb,
773 * and CRYPTO_mem_leaks should be implemented by
774 * using CRYPTO_mem_leaks_cb.
775 * (Also their should be a variant of lh_doall_arg
776 * that takes a function pointer instead of a void *;
777 * this would obviate the ugly and illegal
778 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
779 * Otherwise the code police will come and get us.)
783 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
785 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
786 * which uses CRYPTO_is_mem_check_on */
787 old_mh_mode = mh_mode;
788 mh_mode = CRYPTO_MEM_CHECK_OFF;
797 if (lh_num_items(amih) == 0)
804 mh_mode = old_mh_mode;
805 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
807 MemCheck_on(); /* release MALLOC2 lock */
810 #ifndef OPENSSL_NO_FP_API
811 void CRYPTO_mem_leaks_fp(FILE *fp)
815 if (mh == NULL) return;
816 /* Need to turn off memory checking when allocated BIOs ... especially
817 * as we're creating them at a time when we're trying to check we've not
818 * left anything un-free()'d!! */
820 b = BIO_new(BIO_s_file());
823 BIO_set_fp(b,fp,BIO_NOCLOSE);
831 /* FIXME: We really don't allow much to the callback. For example, it has
832 no chance of reaching the info stack for the item it processes. Should
833 it really be this way? -- Richard Levitte */
834 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
835 * If this code is restructured, remove the callback type if it is no longer
836 * needed. -- Geoff Thorpe */
837 static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
839 (**cb)(m->order,m->file,m->line,m->num,m->addr);
842 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
844 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
846 if (mh == NULL) return;
847 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
848 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
849 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);