Delete nonexistant function from pkcs7.h header file. WIN32 build fix from
[openssl.git] / crypto / mem_dbg.c
1 /* crypto/mem_dbg.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
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.
8  * 
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).
15  * 
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.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
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)"
40  * 
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
51  * SUCH DAMAGE.
52  * 
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.]
57  */
58 /* ====================================================================
59  * Copyright (c) 1998-2006 The OpenSSL Project.  All rights reserved.
60  *
61  * Redistribution and use in source and binary forms, with or without
62  * modification, are permitted provided that the following conditions
63  * are met:
64  *
65  * 1. Redistributions of source code must retain the above copyright
66  *    notice, this list of conditions and the following disclaimer. 
67  *
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
71  *    distribution.
72  *
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/)"
77  *
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.
82  *
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.
86  *
87  * 6. Redistributions of any form whatsoever must retain the following
88  *    acknowledgment:
89  *    "This product includes software developed by the OpenSSL Project
90  *    for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91  *
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  * ====================================================================
105  *
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).
109  *
110  */
111
112 #include <stdio.h>
113 #include <stdlib.h>
114 #include <time.h>       
115 #include "cryptlib.h"
116 #include <openssl/crypto.h>
117 #include <openssl/buffer.h>
118 #include <openssl/bio.h>
119 #include <openssl/lhash.h>
120
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).
125  *
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
131  * temporarily.
132  *
133  * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
134  */
135
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 */
139
140
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.
148  */
149         {
150         CRYPTO_THREADID threadid;
151         const char *file;
152         int line;
153         const char *info;
154         struct app_mem_info_st *next; /* tail of thread's stack */
155         int references;
156         } APP_INFO;
157
158 static void app_info_free(APP_INFO *);
159
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 */
164
165 typedef struct mem_st
166 /* memory-block description */
167         {
168         void *addr;
169         int num;
170         const char *file;
171         int line;
172         CRYPTO_THREADID threadid;
173         unsigned long order;
174         time_t time;
175         APP_INFO *app_info;
176         } MEM;
177
178 static long options =             /* extra information to be recorded */
179 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
180         V_CRYPTO_MDEBUG_TIME |
181 #endif
182 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
183         V_CRYPTO_MDEBUG_THREAD |
184 #endif
185         0;
186
187
188 static unsigned int num_disable = 0; /* num_disable > 0
189                                       *     iff
190                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
191                                       */
192
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;
196
197 static void app_info_free(APP_INFO *inf)
198         {
199         if (--(inf->references) <= 0)
200                 {
201                 if (inf->next != NULL)
202                         {
203                         app_info_free(inf->next);
204                         }
205                 OPENSSL_free(inf);
206                 }
207         }
208
209 int CRYPTO_mem_ctrl(int mode)
210         {
211         int ret=mh_mode;
212
213         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
214         switch (mode)
215                 {
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;
220                 num_disable = 0;
221                 break;
222         case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
223                 mh_mode = 0;
224                 num_disable = 0; /* should be true *before* MemCheck_stop is used,
225                                     or there'll be a lot of confusion */
226                 break;
227
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)
231                         {
232                         CRYPTO_THREADID tid;
233                         CRYPTO_THREADID_set(&tid);
234                         if (!num_disable || CRYPTO_THREADID_cmp(&tid,
235                                                 &disabling_threadid))
236                                 {
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).
243                                  */
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);
254                                 }
255                         num_disable++;
256                         }
257                 break;
258         case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
259                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
260                         {
261                         if (num_disable) /* always true, or something is going wrong */
262                                 {
263                                 num_disable--;
264                                 if (num_disable == 0)
265                                         {
266                                         mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
267                                         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
268                                         }
269                                 }
270                         }
271                 break;
272
273         default:
274                 break;
275                 }
276         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
277         return(ret);
278         }
279
280 int CRYPTO_is_mem_check_on(void)
281         {
282         int ret = 0;
283
284         if (mh_mode & CRYPTO_MEM_CHECK_ON)
285                 {
286                 CRYPTO_THREADID tid;
287                 CRYPTO_THREADID_set(&tid);
288                 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
289
290                 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) ||
291                         CRYPTO_THREADID_cmp(&tid, &disabling_threadid);
292
293                 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
294                 }
295         return(ret);
296         }       
297
298
299 void CRYPTO_dbg_set_options(long bits)
300         {
301         options = bits;
302         }
303
304 long CRYPTO_dbg_get_options(void)
305         {
306         return options;
307         }
308
309 /* static int mem_cmp(MEM *a, MEM *b) */
310 static int mem_cmp(const void *a_void, const void *b_void)
311         {
312 #ifdef _WIN64
313         const char *a=(const char *)((const MEM *)a_void)->addr,
314                    *b=(const char *)((const MEM *)b_void)->addr;
315         if (a==b)       return 0;
316         else if (a>b)   return 1;
317         else            return -1;
318 #else
319         return((const char *)((const MEM *)a_void)->addr
320                 - (const char *)((const MEM *)b_void)->addr);
321 #endif
322         }
323
324 /* static unsigned long mem_hash(MEM *a) */
325 static unsigned long mem_hash(const void *a_void)
326         {
327         unsigned long ret;
328
329         ret=(unsigned long)((const MEM *)a_void)->addr;
330
331         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
332         return(ret);
333         }
334
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)
337         {
338         return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
339                                 &((const APP_INFO *)b_void)->threadid);
340         }
341
342 /* static unsigned long app_info_hash(APP_INFO *a) */
343 static unsigned long app_info_hash(const void *a_void)
344         {
345         unsigned long ret;
346         ret = CRYPTO_THREADID_hash(&((const APP_INFO *)a_void)->threadid);
347         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
348         return(ret);
349         }
350
351 static APP_INFO *pop_info(void)
352         {
353         APP_INFO tmp;
354         APP_INFO *ret = NULL;
355
356         if (amih != NULL)
357                 {
358                 CRYPTO_THREADID_set(&tmp.threadid);
359                 if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
360                         {
361                         APP_INFO *next=ret->next;
362
363                         if (next != NULL)
364                                 {
365                                 next->references++;
366                                 lh_insert(amih,(char *)next);
367                                 }
368 #ifdef LEVITTE_DEBUG_MEM
369                         if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
370                                 {
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));
374                                 abort();
375                                 }
376 #endif
377                         if (--(ret->references) <= 0)
378                                 {
379                                 ret->next = NULL;
380                                 if (next != NULL)
381                                         next->references--;
382                                 OPENSSL_free(ret);
383                                 }
384                         }
385                 }
386         return(ret);
387         }
388
389 int CRYPTO_push_info_(const char *info, const char *file, int line)
390         {
391         APP_INFO *ami, *amim;
392         int ret=0;
393
394         if (is_MemCheck_on())
395                 {
396                 MemCheck_off(); /* obtain MALLOC2 lock */
397
398                 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
399                         {
400                         ret=0;
401                         goto err;
402                         }
403                 if (amih == NULL)
404                         {
405                         if ((amih=lh_new(app_info_hash, app_info_cmp)) == NULL)
406                                 {
407                                 OPENSSL_free(ami);
408                                 ret=0;
409                                 goto err;
410                                 }
411                         }
412
413                 CRYPTO_THREADID_set(&ami->threadid);
414                 ami->file=file;
415                 ami->line=line;
416                 ami->info=info;
417                 ami->references=1;
418                 ami->next=NULL;
419
420                 if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
421                         {
422 #ifdef LEVITTE_DEBUG_MEM
423                         if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
424                                 {
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));
428                                 abort();
429                                 }
430 #endif
431                         ami->next=amim;
432                         }
433  err:
434                 MemCheck_on(); /* release MALLOC2 lock */
435                 }
436
437         return(ret);
438         }
439
440 int CRYPTO_pop_info(void)
441         {
442         int ret=0;
443
444         if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
445                 {
446                 MemCheck_off(); /* obtain MALLOC2 lock */
447
448                 ret=(pop_info() != NULL);
449
450                 MemCheck_on(); /* release MALLOC2 lock */
451                 }
452         return(ret);
453         }
454
455 int CRYPTO_remove_all_info(void)
456         {
457         int ret=0;
458
459         if (is_MemCheck_on()) /* _must_ be true */
460                 {
461                 MemCheck_off(); /* obtain MALLOC2 lock */
462
463                 while(pop_info() != NULL)
464                         ret++;
465
466                 MemCheck_on(); /* release MALLOC2 lock */
467                 }
468         return(ret);
469         }
470
471
472 static unsigned long break_order_num=0;
473 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
474         int before_p)
475         {
476         MEM *m,*mm;
477         APP_INFO tmp,*amim;
478
479         switch(before_p & 127)
480                 {
481         case 0:
482                 break;
483         case 1:
484                 if (addr == NULL)
485                         break;
486
487                 if (is_MemCheck_on())
488                         {
489                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
490                         if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
491                                 {
492                                 OPENSSL_free(addr);
493                                 MemCheck_on(); /* release MALLOC2 lock
494                                                 * if num_disabled drops to 0 */
495                                 return;
496                                 }
497                         if (mh == NULL)
498                                 {
499                                 if ((mh=lh_new(mem_hash, mem_cmp)) == NULL)
500                                         {
501                                         OPENSSL_free(addr);
502                                         OPENSSL_free(m);
503                                         addr=NULL;
504                                         goto err;
505                                         }
506                                 }
507
508                         m->addr=addr;
509                         m->file=file;
510                         m->line=line;
511                         m->num=num;
512                         CRYPTO_THREADID_set(&m->threadid);
513
514                         if (order == break_order_num)
515                                 {
516                                 /* BREAK HERE */
517                                 m->order=order;
518                                 }
519                         m->order=order++;
520 #ifdef LEVITTE_DEBUG_MEM
521                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
522                                 m->order,
523                                 (before_p & 128) ? '*' : '+',
524                                 m->addr, m->num);
525 #endif
526                         if (options & V_CRYPTO_MDEBUG_TIME)
527                                 m->time=time(NULL);
528                         else
529                                 m->time=0;
530
531                         CRYPTO_THREADID_set(&m->threadid);
532                         m->app_info=NULL;
533                         if (amih != NULL
534                                 && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL)
535                                 {
536                                 m->app_info = amim;
537                                 amim->references++;
538                                 }
539
540                         if ((mm=(MEM *)lh_insert(mh,(char *)m)) != NULL)
541                                 {
542                                 /* Not good, but don't sweat it */
543                                 if (mm->app_info != NULL)
544                                         {
545                                         mm->app_info->references--;
546                                         }
547                                 OPENSSL_free(mm);
548                                 }
549                 err:
550                         MemCheck_on(); /* release MALLOC2 lock
551                                         * if num_disabled drops to 0 */
552                         }
553                 break;
554                 }
555         return;
556         }
557
558 void CRYPTO_dbg_free(void *addr, int before_p)
559         {
560         MEM m,*mp;
561
562         switch(before_p)
563                 {
564         case 0:
565                 if (addr == NULL)
566                         break;
567
568                 if (is_MemCheck_on() && (mh != NULL))
569                         {
570                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
571
572                         m.addr=addr;
573                         mp=(MEM *)lh_delete(mh,(char *)&m);
574                         if (mp != NULL)
575                                 {
576 #ifdef LEVITTE_DEBUG_MEM
577                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
578                                 mp->order, mp->addr, mp->num);
579 #endif
580                                 if (mp->app_info != NULL)
581                                         app_info_free(mp->app_info);
582                                 OPENSSL_free(mp);
583                                 }
584
585                         MemCheck_on(); /* release MALLOC2 lock
586                                         * if num_disabled drops to 0 */
587                         }
588                 break;
589         case 1:
590                 break;
591                 }
592         }
593
594 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
595         const char *file, int line, int before_p)
596         {
597         MEM m,*mp;
598
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);
602 #endif
603
604         switch(before_p)
605                 {
606         case 0:
607                 break;
608         case 1:
609                 if (addr2 == NULL)
610                         break;
611
612                 if (addr1 == NULL)
613                         {
614                         CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
615                         break;
616                         }
617
618                 if (is_MemCheck_on())
619                         {
620                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
621
622                         m.addr=addr1;
623                         mp=(MEM *)lh_delete(mh,(char *)&m);
624                         if (mp != NULL)
625                                 {
626 #ifdef LEVITTE_DEBUG_MEM
627                                 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
628                                         mp->order,
629                                         mp->addr, mp->num,
630                                         addr2, num);
631 #endif
632                                 mp->addr=addr2;
633                                 mp->num=num;
634                                 lh_insert(mh,(char *)mp);
635                                 }
636
637                         MemCheck_on(); /* release MALLOC2 lock
638                                         * if num_disabled drops to 0 */
639                         }
640                 break;
641                 }
642         return;
643         }
644
645
646 typedef struct mem_leak_st
647         {
648         BIO *bio;
649         int chunks;
650         long bytes;
651         } MEM_LEAK;
652
653 static void print_leak(const MEM *m, MEM_LEAK *l)
654         {
655         char buf[1024];
656         char *bufp = buf;
657         APP_INFO *amip;
658         int ami_cnt;
659         struct tm *lcl = NULL;
660         CRYPTO_THREADID tid;
661
662 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
663
664         if(m->addr == (char *)l->bio)
665             return;
666
667         if (options & V_CRYPTO_MDEBUG_TIME)
668                 {
669                 lcl = localtime(&m->time);
670         
671                 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
672                         lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
673                 bufp += strlen(bufp);
674                 }
675
676         BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
677                 m->order,m->file,m->line);
678         bufp += strlen(bufp);
679
680         if (options & V_CRYPTO_MDEBUG_THREAD)
681                 {
682                 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
683                         CRYPTO_THREADID_hash(&m->threadid));
684                 bufp += strlen(bufp);
685                 }
686
687         BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
688                 m->num,(unsigned long)m->addr);
689         bufp += strlen(bufp);
690
691         BIO_puts(l->bio,buf);
692         
693         l->chunks++;
694         l->bytes+=m->num;
695
696         amip=m->app_info;
697         ami_cnt=0;
698         if (!amip)
699                 return;
700         CRYPTO_THREADID_set(&tid);
701         
702         do
703                 {
704                 int buf_len;
705                 int info_len;
706
707                 ami_cnt++;
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);
712                 buf_len=strlen(buf);
713                 info_len=strlen(amip->info);
714                 if (128 - buf_len - 3 < info_len)
715                         {
716                         memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
717                         buf_len = 128 - 3;
718                         }
719                 else
720                         {
721                         BUF_strlcpy(buf + buf_len, amip->info,
722                                     sizeof buf - buf_len);
723                         buf_len = strlen(buf);
724                         }
725                 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
726                 
727                 BIO_puts(l->bio,buf);
728
729                 amip = amip->next;
730                 }
731         while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &tid));
732
733 #ifdef LEVITTE_DEBUG_MEM
734         if (amip)
735                 {
736                 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
737                 abort();
738                 }
739 #endif
740         }
741
742 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
743
744 void CRYPTO_mem_leaks(BIO *b)
745         {
746         MEM_LEAK ml;
747
748         if (mh == NULL && amih == NULL)
749                 return;
750
751         MemCheck_off(); /* obtain MALLOC2 lock */
752
753         ml.bio=b;
754         ml.bytes=0;
755         ml.chunks=0;
756         if (mh != NULL)
757                 lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak),
758                                 (char *)&ml);
759         if (ml.chunks != 0)
760                 {
761                 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
762                            ml.bytes,ml.chunks);
763                 }
764         else
765                 {
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.)
771                  *
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.)
780                  */
781                 int old_mh_mode;
782
783                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
784
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;
789
790                 if (mh != NULL)
791                         {
792                         lh_free(mh);
793                         mh = NULL;
794                         }
795                 if (amih != NULL)
796                         {
797                         if (lh_num_items(amih) == 0) 
798                                 {
799                                 lh_free(amih);
800                                 amih = NULL;
801                                 }
802                         }
803
804                 mh_mode = old_mh_mode;
805                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
806                 }
807         MemCheck_on(); /* release MALLOC2 lock */
808         }
809
810 #ifndef OPENSSL_NO_FP_API
811 void CRYPTO_mem_leaks_fp(FILE *fp)
812         {
813         BIO *b;
814
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!! */
819         MemCheck_off();
820         b = BIO_new(BIO_s_file());
821         MemCheck_on();
822         if(!b) return;
823         BIO_set_fp(b,fp,BIO_NOCLOSE);
824         CRYPTO_mem_leaks(b);
825         BIO_free(b);
826         }
827 #endif
828
829
830
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)
838         {
839         (**cb)(m->order,m->file,m->line,m->num,m->addr);
840         }
841
842 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *, CRYPTO_MEM_LEAK_CB **)
843
844 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
845         {
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);
850         }