Add support for nameRelativeToCRLIssuer field in distribution point name
[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
138 DECLARE_LHASH_OF(MEM);
139 static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
140                                 * (address as key); access requires
141                                 * MALLOC2 lock */
142
143
144 typedef struct app_mem_info_st
145 /* For application-defined information (static C-string `info')
146  * to be displayed in memory leak list.
147  * Each thread has its own stack.  For applications, there is
148  *   CRYPTO_push_info("...")     to push an entry,
149  *   CRYPTO_pop_info()           to pop an entry,
150  *   CRYPTO_remove_all_info()    to pop all entries.
151  */
152         {
153         unsigned long thread_id;
154         void *thread_idptr;
155         const char *file;
156         int line;
157         const char *info;
158         struct app_mem_info_st *next; /* tail of thread's stack */
159         int references;
160         } APP_INFO;
161
162 static void app_info_free(APP_INFO *);
163
164 DECLARE_LHASH_OF(APP_INFO);
165 static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
166                                        * app_mem_info_st's that are at
167                                        * the top of their thread's
168                                        * stack (with `thread' as key);
169                                        * access requires MALLOC2
170                                        * lock */
171
172 typedef struct mem_st
173 /* memory-block description */
174         {
175         void *addr;
176         int num;
177         const char *file;
178         int line;
179         unsigned long thread_id;
180         void *thread_idptr;
181         unsigned long order;
182         time_t time;
183         APP_INFO *app_info;
184         } MEM;
185
186 static long options =             /* extra information to be recorded */
187 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
188         V_CRYPTO_MDEBUG_TIME |
189 #endif
190 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
191         V_CRYPTO_MDEBUG_THREAD |
192 #endif
193         0;
194
195
196 static unsigned int num_disable = 0; /* num_disable > 0
197                                       *     iff
198                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
199                                       */
200
201 /* The following two variables, disabling_thread_id and disabling_thread_idptr,
202  * are valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in
203  * this case (by the thread named in disabling_thread_id / disabling_thread_idptr).
204  */
205 static unsigned long disabling_thread_id = 0;
206 static void *disabling_thread_idptr = NULL;
207
208 static void app_info_free(APP_INFO *inf)
209         {
210         if (--(inf->references) <= 0)
211                 {
212                 if (inf->next != NULL)
213                         {
214                         app_info_free(inf->next);
215                         }
216                 OPENSSL_free(inf);
217                 }
218         }
219
220 int CRYPTO_mem_ctrl(int mode)
221         {
222         int ret=mh_mode;
223
224         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
225         switch (mode)
226                 {
227         /* for applications (not to be called while multiple threads
228          * use the library): */
229         case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
230                 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
231                 num_disable = 0;
232                 break;
233         case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
234                 mh_mode = 0;
235                 num_disable = 0; /* should be true *before* MemCheck_stop is used,
236                                     or there'll be a lot of confusion */
237                 break;
238
239         /* switch off temporarily (for library-internal use): */
240         case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
241                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
242                         {
243                         if (!num_disable
244                             || (disabling_thread_id != CRYPTO_thread_id())
245                             || (disabling_thread_idptr != CRYPTO_thread_idptr())) /* otherwise we already have the MALLOC2 lock */
246                                 {
247                                 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
248                                  * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
249                                  * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
250                                  * it because we block entry to this function).
251                                  * Give them a chance, first, and then claim the locks in
252                                  * appropriate order (long-time lock first).
253                                  */
254                                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
255                                 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
256                                  * and CRYPTO_LOCK_MALLOC, we'll still be in the right
257                                  * "case" and "if" branch because MemCheck_start and
258                                  * MemCheck_stop may never be used while there are multiple
259                                  * OpenSSL threads. */
260                                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
261                                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
262                                 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
263                                 disabling_thread_id=CRYPTO_thread_id();
264                                 disabling_thread_idptr=CRYPTO_thread_idptr();
265                                 }
266                         num_disable++;
267                         }
268                 break;
269         case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
270                 if (mh_mode & CRYPTO_MEM_CHECK_ON)
271                         {
272                         if (num_disable) /* always true, or something is going wrong */
273                                 {
274                                 num_disable--;
275                                 if (num_disable == 0)
276                                         {
277                                         mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
278                                         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
279                                         }
280                                 }
281                         }
282                 break;
283
284         default:
285                 break;
286                 }
287         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
288         return(ret);
289         }
290
291 int CRYPTO_is_mem_check_on(void)
292         {
293         int ret = 0;
294
295         if (mh_mode & CRYPTO_MEM_CHECK_ON)
296                 {
297                 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
298
299                 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
300                         || (disabling_thread_id != CRYPTO_thread_id())
301                         || (disabling_thread_idptr != CRYPTO_thread_idptr());
302
303                 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
304                 }
305         return(ret);
306         }       
307
308
309 void CRYPTO_dbg_set_options(long bits)
310         {
311         options = bits;
312         }
313
314 long CRYPTO_dbg_get_options(void)
315         {
316         return options;
317         }
318
319 static int mem_cmp(const MEM *a, const MEM *b)
320         {
321 #ifdef _WIN64
322         const char *ap=(const char *)a->addr,
323                    *bp=(const char *)b->addr;
324         if (ap==bp)     return 0;
325         else if (ap>bp) return 1;
326         else            return -1;
327 #else
328         return (const char *)a->addr - (const char *)b->addr;
329 #endif
330         }
331 static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
332
333 static unsigned long mem_hash(const MEM *a)
334         {
335         unsigned long ret;
336
337         ret=(unsigned long)a->addr;
338
339         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
340         return(ret);
341         }
342 static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
343
344 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
345 static int app_info_cmp(const void *a_void, const void *b_void)
346         {
347         return (((const APP_INFO *)a_void)->thread_id != ((const APP_INFO *)b_void)->thread_id)
348                || (((const APP_INFO *)a_void)->thread_idptr != ((const APP_INFO *)b_void)->thread_idptr);
349         }
350 static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
351
352 static unsigned long app_info_hash(const APP_INFO *a)
353         {
354         unsigned long id1, id2;
355         unsigned long ret;
356
357         id1=(unsigned long)a->thread_id;
358         id2=(unsigned long)a->thread_idptr;
359         ret = id1 + id2;
360
361         ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
362         return(ret);
363         }
364 static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
365
366 static APP_INFO *pop_info(void)
367         {
368         APP_INFO tmp;
369         APP_INFO *ret = NULL;
370
371         if (amih != NULL)
372                 {
373                 tmp.thread_id=CRYPTO_thread_id();
374                 tmp.thread_idptr=CRYPTO_thread_idptr();
375                 if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
376                         {
377                         APP_INFO *next=ret->next;
378
379                         if (next != NULL)
380                                 {
381                                 next->references++;
382                                 (void)lh_APP_INFO_insert(amih,next);
383                                 }
384 #ifdef LEVITTE_DEBUG_MEM
385                         if (ret->thread_id != tmp.thread_id || ret->thread_idptr != tmp.thread_idptr)
386                                 {
387                                 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
388                                         ret->thread_id, ret->thread_idptr, tmp.thread_id, tmp.thread_idptr);
389                                 abort();
390                                 }
391 #endif
392                         if (--(ret->references) <= 0)
393                                 {
394                                 ret->next = NULL;
395                                 if (next != NULL)
396                                         next->references--;
397                                 OPENSSL_free(ret);
398                                 }
399                         }
400                 }
401         return(ret);
402         }
403
404 int CRYPTO_push_info_(const char *info, const char *file, int line)
405         {
406         APP_INFO *ami, *amim;
407         int ret=0;
408
409         if (is_MemCheck_on())
410                 {
411                 MemCheck_off(); /* obtain MALLOC2 lock */
412
413                 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
414                         {
415                         ret=0;
416                         goto err;
417                         }
418                 if (amih == NULL)
419                         {
420                         if ((amih=lh_APP_INFO_new()) == NULL)
421                                 {
422                                 OPENSSL_free(ami);
423                                 ret=0;
424                                 goto err;
425                                 }
426                         }
427
428                 ami->thread_id=CRYPTO_thread_id();
429                 ami->thread_idptr=CRYPTO_thread_idptr();
430                 ami->file=file;
431                 ami->line=line;
432                 ami->info=info;
433                 ami->references=1;
434                 ami->next=NULL;
435
436                 if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
437                         {
438 #ifdef LEVITTE_DEBUG_MEM
439                         if (ami->thread_id != amim->thread_id || ami->thread_idptr != amim->thread_idptr)
440                                 {
441                                 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
442                                         amim->thread_id, amim->thread_idptr, ami->thread_id, ami->thread_idptr);
443                                 abort();
444                                 }
445 #endif
446                         ami->next=amim;
447                         }
448  err:
449                 MemCheck_on(); /* release MALLOC2 lock */
450                 }
451
452         return(ret);
453         }
454
455 int CRYPTO_pop_info(void)
456         {
457         int ret=0;
458
459         if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
460                 {
461                 MemCheck_off(); /* obtain MALLOC2 lock */
462
463                 ret=(pop_info() != NULL);
464
465                 MemCheck_on(); /* release MALLOC2 lock */
466                 }
467         return(ret);
468         }
469
470 int CRYPTO_remove_all_info(void)
471         {
472         int ret=0;
473
474         if (is_MemCheck_on()) /* _must_ be true */
475                 {
476                 MemCheck_off(); /* obtain MALLOC2 lock */
477
478                 while(pop_info() != NULL)
479                         ret++;
480
481                 MemCheck_on(); /* release MALLOC2 lock */
482                 }
483         return(ret);
484         }
485
486
487 static unsigned long break_order_num=0;
488 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
489         int before_p)
490         {
491         MEM *m,*mm;
492         APP_INFO tmp,*amim;
493
494         switch(before_p & 127)
495                 {
496         case 0:
497                 break;
498         case 1:
499                 if (addr == NULL)
500                         break;
501
502                 if (is_MemCheck_on())
503                         {
504                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
505                         if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
506                                 {
507                                 OPENSSL_free(addr);
508                                 MemCheck_on(); /* release MALLOC2 lock
509                                                 * if num_disabled drops to 0 */
510                                 return;
511                                 }
512                         if (mh == NULL)
513                                 {
514                                 if ((mh=lh_MEM_new()) == NULL)
515                                         {
516                                         OPENSSL_free(addr);
517                                         OPENSSL_free(m);
518                                         addr=NULL;
519                                         goto err;
520                                         }
521                                 }
522
523                         m->addr=addr;
524                         m->file=file;
525                         m->line=line;
526                         m->num=num;
527                         if (options & V_CRYPTO_MDEBUG_THREAD)
528                                 {
529                                 m->thread_id=CRYPTO_thread_id();
530                                 m->thread_idptr=CRYPTO_thread_idptr();
531                                 }
532                         else
533                                 {
534                                 m->thread_id=0;
535                                 m->thread_idptr=NULL;
536                                 }
537
538                         if (order == break_order_num)
539                                 {
540                                 /* BREAK HERE */
541                                 m->order=order;
542                                 }
543                         m->order=order++;
544 #ifdef LEVITTE_DEBUG_MEM
545                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
546                                 m->order,
547                                 (before_p & 128) ? '*' : '+',
548                                 m->addr, m->num);
549 #endif
550                         if (options & V_CRYPTO_MDEBUG_TIME)
551                                 m->time=time(NULL);
552                         else
553                                 m->time=0;
554
555                         tmp.thread_id=CRYPTO_thread_id();
556                         tmp.thread_idptr=CRYPTO_thread_idptr();
557                         m->app_info=NULL;
558                         if (amih != NULL
559                             && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
560                                 {
561                                 m->app_info = amim;
562                                 amim->references++;
563                                 }
564
565                         if ((mm=lh_MEM_insert(mh, m)) != NULL)
566                                 {
567                                 /* Not good, but don't sweat it */
568                                 if (mm->app_info != NULL)
569                                         {
570                                         mm->app_info->references--;
571                                         }
572                                 OPENSSL_free(mm);
573                                 }
574                 err:
575                         MemCheck_on(); /* release MALLOC2 lock
576                                         * if num_disabled drops to 0 */
577                         }
578                 break;
579                 }
580         return;
581         }
582
583 void CRYPTO_dbg_free(void *addr, int before_p)
584         {
585         MEM m,*mp;
586
587         switch(before_p)
588                 {
589         case 0:
590                 if (addr == NULL)
591                         break;
592
593                 if (is_MemCheck_on() && (mh != NULL))
594                         {
595                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
596
597                         m.addr=addr;
598                         mp=lh_MEM_delete(mh,&m);
599                         if (mp != NULL)
600                                 {
601 #ifdef LEVITTE_DEBUG_MEM
602                         fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
603                                 mp->order, mp->addr, mp->num);
604 #endif
605                                 if (mp->app_info != NULL)
606                                         app_info_free(mp->app_info);
607                                 OPENSSL_free(mp);
608                                 }
609
610                         MemCheck_on(); /* release MALLOC2 lock
611                                         * if num_disabled drops to 0 */
612                         }
613                 break;
614         case 1:
615                 break;
616                 }
617         }
618
619 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
620         const char *file, int line, int before_p)
621         {
622         MEM m,*mp;
623
624 #ifdef LEVITTE_DEBUG_MEM
625         fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
626                 addr1, addr2, num, file, line, before_p);
627 #endif
628
629         switch(before_p)
630                 {
631         case 0:
632                 break;
633         case 1:
634                 if (addr2 == NULL)
635                         break;
636
637                 if (addr1 == NULL)
638                         {
639                         CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
640                         break;
641                         }
642
643                 if (is_MemCheck_on())
644                         {
645                         MemCheck_off(); /* make sure we hold MALLOC2 lock */
646
647                         m.addr=addr1;
648                         mp=lh_MEM_delete(mh,&m);
649                         if (mp != NULL)
650                                 {
651 #ifdef LEVITTE_DEBUG_MEM
652                                 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
653                                         mp->order,
654                                         mp->addr, mp->num,
655                                         addr2, num);
656 #endif
657                                 mp->addr=addr2;
658                                 mp->num=num;
659                                 (void)lh_MEM_insert(mh,mp);
660                                 }
661
662                         MemCheck_on(); /* release MALLOC2 lock
663                                         * if num_disabled drops to 0 */
664                         }
665                 break;
666                 }
667         return;
668         }
669
670
671 typedef struct mem_leak_st
672         {
673         BIO *bio;
674         int chunks;
675         long bytes;
676         } MEM_LEAK;
677
678 static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
679         {
680         char buf[1024];
681         char *bufp = buf;
682         APP_INFO *amip;
683         int ami_cnt;
684         struct tm *lcl = NULL;
685         unsigned long ti;
686         void *tip;
687
688 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
689
690         if(m->addr == (char *)l->bio)
691             return;
692
693         if (options & V_CRYPTO_MDEBUG_TIME)
694                 {
695                 lcl = localtime(&m->time);
696         
697                 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
698                         lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
699                 bufp += strlen(bufp);
700                 }
701
702         BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
703                 m->order,m->file,m->line);
704         bufp += strlen(bufp);
705
706         if (options & V_CRYPTO_MDEBUG_THREAD)
707                 {
708                 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu/%p, ", m->thread_id, m->thread_idptr);
709                 bufp += strlen(bufp);
710                 }
711
712         BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
713                 m->num,(unsigned long)m->addr);
714         bufp += strlen(bufp);
715
716         BIO_puts(l->bio,buf);
717         
718         l->chunks++;
719         l->bytes+=m->num;
720
721         amip=m->app_info;
722         ami_cnt=0;
723         if (!amip)
724                 return;
725         ti=amip->thread_id;
726         tip=amip->thread_idptr;
727         
728         do
729                 {
730                 int buf_len;
731                 int info_len;
732
733                 ami_cnt++;
734                 memset(buf,'>',ami_cnt);
735                 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
736                         " thread=%lu/%p, file=%s, line=%d, info=\"",
737                         amip->thread_id, amip->thread_idptr, amip->file, amip->line);
738                 buf_len=strlen(buf);
739                 info_len=strlen(amip->info);
740                 if (128 - buf_len - 3 < info_len)
741                         {
742                         memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
743                         buf_len = 128 - 3;
744                         }
745                 else
746                         {
747                         BUF_strlcpy(buf + buf_len, amip->info,
748                                     sizeof buf - buf_len);
749                         buf_len = strlen(buf);
750                         }
751                 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
752                 
753                 BIO_puts(l->bio,buf);
754
755                 amip = amip->next;
756                 }
757         while(amip && amip->thread_id == ti && amip->thread_idptr == tip);
758
759 #ifdef LEVITTE_DEBUG_MEM
760         if (amip)
761                 {
762                 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
763                 abort();
764                 }
765 #endif
766         }
767
768 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
769
770 void CRYPTO_mem_leaks(BIO *b)
771         {
772         MEM_LEAK ml;
773
774         if (mh == NULL && amih == NULL)
775                 return;
776
777         MemCheck_off(); /* obtain MALLOC2 lock */
778
779         ml.bio=b;
780         ml.bytes=0;
781         ml.chunks=0;
782         if (mh != NULL)
783                 lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
784                                  &ml);
785         if (ml.chunks != 0)
786                 {
787                 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
788                            ml.bytes,ml.chunks);
789                 }
790         else
791                 {
792                 /* Make sure that, if we found no leaks, memory-leak debugging itself
793                  * does not introduce memory leaks (which might irritate
794                  * external debugging tools).
795                  * (When someone enables leak checking, but does not call
796                  * this function, we declare it to be their fault.)
797                  *
798                  * XXX    This should be in CRYPTO_mem_leaks_cb,
799                  * and CRYPTO_mem_leaks should be implemented by
800                  * using CRYPTO_mem_leaks_cb.
801                  * (Also their should be a variant of lh_doall_arg
802                  * that takes a function pointer instead of a void *;
803                  * this would obviate the ugly and illegal
804                  * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
805                  * Otherwise the code police will come and get us.)
806                  */
807                 int old_mh_mode;
808
809                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
810
811                 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
812                  * which uses CRYPTO_is_mem_check_on */
813                 old_mh_mode = mh_mode;
814                 mh_mode = CRYPTO_MEM_CHECK_OFF;
815
816                 if (mh != NULL)
817                         {
818                         lh_MEM_free(mh);
819                         mh = NULL;
820                         }
821                 if (amih != NULL)
822                         {
823                         if (lh_APP_INFO_num_items(amih) == 0) 
824                                 {
825                                 lh_APP_INFO_free(amih);
826                                 amih = NULL;
827                                 }
828                         }
829
830                 mh_mode = old_mh_mode;
831                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
832                 }
833         MemCheck_on(); /* release MALLOC2 lock */
834         }
835
836 #ifndef OPENSSL_NO_FP_API
837 void CRYPTO_mem_leaks_fp(FILE *fp)
838         {
839         BIO *b;
840
841         if (mh == NULL) return;
842         /* Need to turn off memory checking when allocated BIOs ... especially
843          * as we're creating them at a time when we're trying to check we've not
844          * left anything un-free()'d!! */
845         MemCheck_off();
846         b = BIO_new(BIO_s_file());
847         MemCheck_on();
848         if(!b) return;
849         BIO_set_fp(b,fp,BIO_NOCLOSE);
850         CRYPTO_mem_leaks(b);
851         BIO_free(b);
852         }
853 #endif
854
855
856
857 /* FIXME: We really don't allow much to the callback.  For example, it has
858    no chance of reaching the info stack for the item it processes.  Should
859    it really be this way?  -- Richard Levitte */
860 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
861  * If this code is restructured, remove the callback type if it is no longer
862  * needed. -- Geoff Thorpe */
863
864 /* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
865  * is a function pointer and conversion to void * is prohibited. Instead
866  * pass its address
867  */
868
869 typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
870
871 static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
872         {
873         (*cb)(m->order,m->file,m->line,m->num,m->addr);
874         }
875
876 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
877
878 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
879         {
880         if (mh == NULL) return;
881         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
882         lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
883                          &cb);
884         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
885         }