]> CyberLeo.Net >> Repos - FreeBSD/releng/9.3.git/blob - crypto/openssl/crypto/mem_dbg.c
Fix multiple OpenSSL vulnerabilities.
[FreeBSD/releng/9.3.git] / crypto / openssl / 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 #include <stdio.h>
60 #include <stdlib.h>
61 #include <time.h>
62 #include "cryptlib.h"
63 #include <openssl/crypto.h>
64 #include <openssl/buffer.h>
65 #include <openssl/bio.h>
66 #include <openssl/lhash.h>
67
68 static int mh_mode = CRYPTO_MEM_CHECK_OFF;
69 /*
70  * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
71  * the application asks for it (usually after library initialisation for
72  * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
73  * temporarily when the library thinks that certain allocations should not be
74  * checked (e.g. the data structures used for memory checking).  It is not
75  * suitable as an initial state: the library will unexpectedly enable memory
76  * checking when it executes one of those sections that want to disable
77  * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
78  * no sense whatsoever.
79  */
80
81 static unsigned long order = 0; /* number of memory requests */
82 static LHASH *mh = NULL;        /* hash-table of memory requests (address as
83                                  * key); access requires MALLOC2 lock */
84
85 typedef struct app_mem_info_st
86 /*-
87  * For application-defined information (static C-string `info')
88  * to be displayed in memory leak list.
89  * Each thread has its own stack.  For applications, there is
90  *   CRYPTO_push_info("...")     to push an entry,
91  *   CRYPTO_pop_info()           to pop an entry,
92  *   CRYPTO_remove_all_info()    to pop all entries.
93  */
94 {
95     unsigned long thread;
96     const char *file;
97     int line;
98     const char *info;
99     struct app_mem_info_st *next; /* tail of thread's stack */
100     int references;
101 } APP_INFO;
102
103 static void app_info_free(APP_INFO *);
104
105 static LHASH *amih = NULL;      /* hash-table with those app_mem_info_st's
106                                  * that are at the top of their thread's
107                                  * stack (with `thread' as key); access
108                                  * requires MALLOC2 lock */
109
110 typedef struct mem_st
111 /* memory-block description */
112 {
113     void *addr;
114     int num;
115     const char *file;
116     int line;
117     unsigned long thread;
118     unsigned long order;
119     time_t time;
120     APP_INFO *app_info;
121 } MEM;
122
123 static long options =           /* extra information to be recorded */
124 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
125     V_CRYPTO_MDEBUG_TIME |
126 #endif
127 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
128     V_CRYPTO_MDEBUG_THREAD |
129 #endif
130     0;
131
132 static unsigned int num_disable = 0; /* num_disable > 0 iff mh_mode ==
133                                       * CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
134 static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0.
135                                             * CRYPTO_LOCK_MALLOC2 is locked
136                                             * exactly in this case (by the
137                                             * thread named in
138                                             * disabling_thread). */
139
140 static void app_info_free(APP_INFO *inf)
141 {
142     if (--(inf->references) <= 0) {
143         if (inf->next != NULL) {
144             app_info_free(inf->next);
145         }
146         OPENSSL_free(inf);
147     }
148 }
149
150 int CRYPTO_mem_ctrl(int mode)
151 {
152     int ret = mh_mode;
153
154     CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
155     switch (mode) {
156         /*
157          * for applications (not to be called while multiple threads use the
158          * library):
159          */
160     case CRYPTO_MEM_CHECK_ON:  /* aka MemCheck_start() */
161         mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
162         num_disable = 0;
163         break;
164     case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
165         mh_mode = 0;
166         num_disable = 0;        /* should be true *before* MemCheck_stop is
167                                  * used, or there'll be a lot of confusion */
168         break;
169
170         /* switch off temporarily (for library-internal use): */
171     case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
172         if (mh_mode & CRYPTO_MEM_CHECK_ON) {
173             /* otherwise we already have the MALLOC2 lock */
174             if (!num_disable || (disabling_thread != CRYPTO_thread_id())) {
175                 /*
176                  * Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed
177                  * while we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock
178                  * if somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot
179                  * release it because we block entry to this function). Give
180                  * them a chance, first, and then claim the locks in
181                  * appropriate order (long-time lock first).
182                  */
183                 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
184                 /*
185                  * Note that after we have waited for CRYPTO_LOCK_MALLOC2 and
186                  * CRYPTO_LOCK_MALLOC, we'll still be in the right "case" and
187                  * "if" branch because MemCheck_start and MemCheck_stop may
188                  * never be used while there are multiple OpenSSL threads.
189                  */
190                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
191                 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
192                 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
193                 disabling_thread = CRYPTO_thread_id();
194             }
195             num_disable++;
196         }
197         break;
198     case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
199         if (mh_mode & CRYPTO_MEM_CHECK_ON) {
200             if (num_disable) {  /* always true, or something is going wrong */
201                 num_disable--;
202                 if (num_disable == 0) {
203                     mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
204                     CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
205                 }
206             }
207         }
208         break;
209
210     default:
211         break;
212     }
213     CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
214     return (ret);
215 }
216
217 int CRYPTO_is_mem_check_on(void)
218 {
219     int ret = 0;
220
221     if (mh_mode & CRYPTO_MEM_CHECK_ON) {
222         CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
223
224         ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
225             || (disabling_thread != CRYPTO_thread_id());
226
227         CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
228     }
229     return (ret);
230 }
231
232 void CRYPTO_dbg_set_options(long bits)
233 {
234     options = bits;
235 }
236
237 long CRYPTO_dbg_get_options(void)
238 {
239     return options;
240 }
241
242 /* static int mem_cmp(MEM *a, MEM *b) */
243 static int mem_cmp(const void *a_void, const void *b_void)
244 {
245 #ifdef _WIN64
246     const char *a = (const char *)((const MEM *)a_void)->addr,
247         *b = (const char *)((const MEM *)b_void)->addr;
248     if (a == b)
249         return 0;
250     else if (a > b)
251         return 1;
252     else
253         return -1;
254 #else
255     return ((const char *)((const MEM *)a_void)->addr
256             - (const char *)((const MEM *)b_void)->addr);
257 #endif
258 }
259
260 /* static unsigned long mem_hash(MEM *a) */
261 static unsigned long mem_hash(const void *a_void)
262 {
263     unsigned long ret;
264
265     ret = (unsigned long)((const MEM *)a_void)->addr;
266
267     ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
268     return (ret);
269 }
270
271 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
272 static int app_info_cmp(const void *a_void, const void *b_void)
273 {
274     return (((const APP_INFO *)a_void)->thread
275             != ((const APP_INFO *)b_void)->thread);
276 }
277
278 /* static unsigned long app_info_hash(APP_INFO *a) */
279 static unsigned long app_info_hash(const void *a_void)
280 {
281     unsigned long ret;
282
283     ret = (unsigned long)((const APP_INFO *)a_void)->thread;
284
285     ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
286     return (ret);
287 }
288
289 static APP_INFO *pop_info(void)
290 {
291     APP_INFO tmp;
292     APP_INFO *ret = NULL;
293
294     if (amih != NULL) {
295         tmp.thread = CRYPTO_thread_id();
296         if ((ret = (APP_INFO *)lh_delete(amih, &tmp)) != NULL) {
297             APP_INFO *next = ret->next;
298
299             if (next != NULL) {
300                 next->references++;
301                 lh_insert(amih, (char *)next);
302             }
303 #ifdef LEVITTE_DEBUG_MEM
304             if (ret->thread != tmp.thread) {
305                 fprintf(stderr,
306                         "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
307                         ret->thread, tmp.thread);
308                 abort();
309             }
310 #endif
311             if (--(ret->references) <= 0) {
312                 ret->next = NULL;
313                 if (next != NULL)
314                     next->references--;
315                 OPENSSL_free(ret);
316             }
317         }
318     }
319     return (ret);
320 }
321
322 int CRYPTO_dbg_push_info(const char *info, const char *file, int line)
323 {
324     APP_INFO *ami, *amim;
325     int ret = 0;
326
327     if (is_MemCheck_on()) {
328         MemCheck_off();         /* obtain MALLOC2 lock */
329
330         if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) {
331             ret = 0;
332             goto err;
333         }
334         if (amih == NULL) {
335             if ((amih = lh_new(app_info_hash, app_info_cmp)) == NULL) {
336                 OPENSSL_free(ami);
337                 ret = 0;
338                 goto err;
339             }
340         }
341
342         ami->thread = CRYPTO_thread_id();
343         ami->file = file;
344         ami->line = line;
345         ami->info = info;
346         ami->references = 1;
347         ami->next = NULL;
348
349         if ((amim = (APP_INFO *)lh_insert(amih, (char *)ami)) != NULL) {
350 #ifdef LEVITTE_DEBUG_MEM
351             if (ami->thread != amim->thread) {
352                 fprintf(stderr,
353                         "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
354                         amim->thread, ami->thread);
355                 abort();
356             }
357 #endif
358             ami->next = amim;
359         }
360  err:
361         MemCheck_on();          /* release MALLOC2 lock */
362     }
363
364     return (ret);
365 }
366
367 int CRYPTO_dbg_pop_info(void)
368 {
369     int ret = 0;
370
371     if (is_MemCheck_on()) {     /* _must_ be true, or something went severely
372                                  * wrong */
373         MemCheck_off();         /* obtain MALLOC2 lock */
374
375         ret = (pop_info() != NULL);
376
377         MemCheck_on();          /* release MALLOC2 lock */
378     }
379     return (ret);
380 }
381
382 int CRYPTO_dbg_remove_all_info(void)
383 {
384     int ret = 0;
385
386     if (is_MemCheck_on()) {     /* _must_ be true */
387         MemCheck_off();         /* obtain MALLOC2 lock */
388
389         while (pop_info() != NULL)
390             ret++;
391
392         MemCheck_on();          /* release MALLOC2 lock */
393     }
394     return (ret);
395 }
396
397 static unsigned long break_order_num = 0;
398 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
399                        int before_p)
400 {
401     MEM *m, *mm;
402     APP_INFO tmp, *amim;
403
404     switch (before_p & 127) {
405     case 0:
406         break;
407     case 1:
408         if (addr == NULL)
409             break;
410
411         if (is_MemCheck_on()) {
412             MemCheck_off();     /* make sure we hold MALLOC2 lock */
413             if ((m = (MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) {
414                 OPENSSL_free(addr);
415                 MemCheck_on();  /* release MALLOC2 lock if num_disabled drops
416                                  * to 0 */
417                 return;
418             }
419             if (mh == NULL) {
420                 if ((mh = lh_new(mem_hash, mem_cmp)) == NULL) {
421                     OPENSSL_free(addr);
422                     OPENSSL_free(m);
423                     addr = NULL;
424                     goto err;
425                 }
426             }
427
428             m->addr = addr;
429             m->file = file;
430             m->line = line;
431             m->num = num;
432             if (options & V_CRYPTO_MDEBUG_THREAD)
433                 m->thread = CRYPTO_thread_id();
434             else
435                 m->thread = 0;
436
437             if (order == break_order_num) {
438                 /* BREAK HERE */
439                 m->order = order;
440             }
441             m->order = order++;
442 #ifdef LEVITTE_DEBUG_MEM
443             fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n",
444                     m->order, (before_p & 128) ? '*' : '+', m->addr, m->num);
445 #endif
446             if (options & V_CRYPTO_MDEBUG_TIME)
447                 m->time = time(NULL);
448             else
449                 m->time = 0;
450
451             tmp.thread = CRYPTO_thread_id();
452             m->app_info = NULL;
453             if (amih != NULL
454                 && (amim =
455                     (APP_INFO *)lh_retrieve(amih, (char *)&tmp)) != NULL) {
456                 m->app_info = amim;
457                 amim->references++;
458             }
459
460             if ((mm = (MEM *)lh_insert(mh, (char *)m)) != NULL) {
461                 /* Not good, but don't sweat it */
462                 if (mm->app_info != NULL) {
463                     mm->app_info->references--;
464                 }
465                 OPENSSL_free(mm);
466             }
467  err:
468             MemCheck_on();      /* release MALLOC2 lock if num_disabled drops
469                                  * to 0 */
470         }
471         break;
472     }
473     return;
474 }
475
476 void CRYPTO_dbg_free(void *addr, int before_p)
477 {
478     MEM m, *mp;
479
480     switch (before_p) {
481     case 0:
482         if (addr == NULL)
483             break;
484
485         if (is_MemCheck_on() && (mh != NULL)) {
486             MemCheck_off();     /* make sure we hold MALLOC2 lock */
487
488             m.addr = addr;
489             mp = (MEM *)lh_delete(mh, (char *)&m);
490             if (mp != NULL) {
491 #ifdef LEVITTE_DEBUG_MEM
492                 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n",
493                         mp->order, mp->addr, mp->num);
494 #endif
495                 if (mp->app_info != NULL)
496                     app_info_free(mp->app_info);
497                 OPENSSL_free(mp);
498             }
499
500             MemCheck_on();      /* release MALLOC2 lock if num_disabled drops
501                                  * to 0 */
502         }
503         break;
504     case 1:
505         break;
506     }
507 }
508
509 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
510                         const char *file, int line, int before_p)
511 {
512     MEM m, *mp;
513
514 #ifdef LEVITTE_DEBUG_MEM
515     fprintf(stderr,
516             "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
517             addr1, addr2, num, file, line, before_p);
518 #endif
519
520     switch (before_p) {
521     case 0:
522         break;
523     case 1:
524         if (addr2 == NULL)
525             break;
526
527         if (addr1 == NULL) {
528             CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
529             break;
530         }
531
532         if (is_MemCheck_on()) {
533             MemCheck_off();     /* make sure we hold MALLOC2 lock */
534
535             m.addr = addr1;
536             mp = (MEM *)lh_delete(mh, (char *)&m);
537             if (mp != NULL) {
538 #ifdef LEVITTE_DEBUG_MEM
539                 fprintf(stderr,
540                         "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n",
541                         mp->order, mp->addr, mp->num, addr2, num);
542 #endif
543                 mp->addr = addr2;
544                 mp->num = num;
545                 lh_insert(mh, (char *)mp);
546             }
547
548             MemCheck_on();      /* release MALLOC2 lock if num_disabled drops
549                                  * to 0 */
550         }
551         break;
552     }
553     return;
554 }
555
556 typedef struct mem_leak_st {
557     BIO *bio;
558     int chunks;
559     long bytes;
560 } MEM_LEAK;
561
562 static void print_leak(const MEM *m, MEM_LEAK *l)
563 {
564     char buf[1024];
565     char *bufp = buf;
566     APP_INFO *amip;
567     int ami_cnt;
568     struct tm *lcl = NULL;
569     unsigned long ti;
570
571 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
572
573     if (m->addr == (char *)l->bio)
574         return;
575
576     if (options & V_CRYPTO_MDEBUG_TIME) {
577         lcl = localtime(&m->time);
578
579         BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
580                      lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
581         bufp += strlen(bufp);
582     }
583
584     BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
585                  m->order, m->file, m->line);
586     bufp += strlen(bufp);
587
588     if (options & V_CRYPTO_MDEBUG_THREAD) {
589         BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread);
590         bufp += strlen(bufp);
591     }
592
593     BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
594                  m->num, (unsigned long)m->addr);
595     bufp += strlen(bufp);
596
597     BIO_puts(l->bio, buf);
598
599     l->chunks++;
600     l->bytes += m->num;
601
602     amip = m->app_info;
603     ami_cnt = 0;
604     if (!amip)
605         return;
606     ti = amip->thread;
607
608     do {
609         int buf_len;
610         int info_len;
611
612         ami_cnt++;
613         memset(buf, '>', ami_cnt);
614         BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
615                      " thread=%lu, file=%s, line=%d, info=\"",
616                      amip->thread, amip->file, amip->line);
617         buf_len = strlen(buf);
618         info_len = strlen(amip->info);
619         if (128 - buf_len - 3 < info_len) {
620             memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
621             buf_len = 128 - 3;
622         } else {
623             BUF_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
624             buf_len = strlen(buf);
625         }
626         BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
627
628         BIO_puts(l->bio, buf);
629
630         amip = amip->next;
631     }
632     while (amip && amip->thread == ti);
633
634 #ifdef LEVITTE_DEBUG_MEM
635     if (amip) {
636         fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
637         abort();
638     }
639 #endif
640 }
641
642 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM *, MEM_LEAK *)
643
644 void CRYPTO_mem_leaks(BIO *b)
645 {
646     MEM_LEAK ml;
647
648     if (mh == NULL && amih == NULL)
649         return;
650
651     MemCheck_off();             /* obtain MALLOC2 lock */
652
653     ml.bio = b;
654     ml.bytes = 0;
655     ml.chunks = 0;
656     if (mh != NULL)
657         lh_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), (char *)&ml);
658     if (ml.chunks != 0) {
659         BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks);
660     } else {
661         /*
662          * Make sure that, if we found no leaks, memory-leak debugging itself
663          * does not introduce memory leaks (which might irritate external
664          * debugging tools). (When someone enables leak checking, but does not
665          * call this function, we declare it to be their fault.) XXX This
666          * should be in CRYPTO_mem_leaks_cb, and CRYPTO_mem_leaks should be
667          * implemented by using CRYPTO_mem_leaks_cb. (Also their should be a
668          * variant of lh_doall_arg that takes a function pointer instead of a
669          * void *; this would obviate the ugly and illegal void_fn_to_char
670          * kludge in CRYPTO_mem_leaks_cb. Otherwise the code police will come
671          * and get us.)
672          */
673         int old_mh_mode;
674
675         CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
676
677         /*
678          * avoid deadlock when lh_free() uses CRYPTO_dbg_free(), which uses
679          * CRYPTO_is_mem_check_on
680          */
681         old_mh_mode = mh_mode;
682         mh_mode = CRYPTO_MEM_CHECK_OFF;
683
684         if (mh != NULL) {
685             lh_free(mh);
686             mh = NULL;
687         }
688         if (amih != NULL) {
689             if (lh_num_items(amih) == 0) {
690                 lh_free(amih);
691                 amih = NULL;
692             }
693         }
694
695         mh_mode = old_mh_mode;
696         CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
697     }
698     MemCheck_on();              /* release MALLOC2 lock */
699 }
700
701 #ifndef OPENSSL_NO_FP_API
702 void CRYPTO_mem_leaks_fp(FILE *fp)
703 {
704     BIO *b;
705
706     if (mh == NULL)
707         return;
708     /*
709      * Need to turn off memory checking when allocated BIOs ... especially as
710      * we're creating them at a time when we're trying to check we've not
711      * left anything un-free()'d!!
712      */
713     MemCheck_off();
714     b = BIO_new(BIO_s_file());
715     MemCheck_on();
716     if (!b)
717         return;
718     BIO_set_fp(b, fp, BIO_NOCLOSE);
719     CRYPTO_mem_leaks(b);
720     BIO_free(b);
721 }
722 #endif
723
724 /*
725  * FIXME: We really don't allow much to the callback.  For example, it has no
726  * chance of reaching the info stack for the item it processes.  Should it
727  * really be this way? -- Richard Levitte
728  */
729 /*
730  * NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside
731  * crypto.h If this code is restructured, remove the callback type if it is
732  * no longer needed. -- Geoff Thorpe
733  */
734 static void cb_leak(const MEM *m, CRYPTO_MEM_LEAK_CB **cb)
735 {
736     (**cb) (m->order, m->file, m->line, m->num, m->addr);
737 }
738
739 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM *,
740                                     CRYPTO_MEM_LEAK_CB **)
741
742 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
743 {
744     if (mh == NULL)
745         return;
746     CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
747     lh_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), &cb);
748     CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
749 }
750
751 void CRYPTO_malloc_debug_init(void)
752 {
753     CRYPTO_set_mem_debug_functions(CRYPTO_dbg_malloc,
754                                    CRYPTO_dbg_realloc,
755                                    CRYPTO_dbg_free,
756                                    CRYPTO_dbg_set_options,
757                                    CRYPTO_dbg_get_options);
758     CRYPTO_set_mem_info_functions(CRYPTO_dbg_push_info,
759                                   CRYPTO_dbg_pop_info,
760                                   CRYPTO_dbg_remove_all_info);
761 }
762
763 char *CRYPTO_strdup(const char *str, const char *file, int line)
764 {
765     char *ret = CRYPTO_malloc(strlen(str) + 1, file, line);
766
767     strcpy(ret, str);
768     return ret;
769 }