0307c0251723749d1d63aa28ddb614cc4efcfcf2
[openssl.git] / crypto / mem_dbg.c
1 /*
2  * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
3  *
4  * Licensed under the OpenSSL license (the "License").  You may not use
5  * this file except in compliance with the License.  You can obtain a copy
6  * in the file LICENSE in the source distribution or at
7  * https://www.openssl.org/source/license.html
8  */
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <time.h>
13 #include "internal/cryptlib.h"
14 #include <openssl/crypto.h>
15 #include <openssl/buffer.h>
16 #include "internal/bio.h"
17 #include <openssl/lhash.h>
18
19 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
20 # include <execinfo.h>
21 #endif
22
23 /*
24  * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
25  * the application asks for it (usually after library initialisation for
26  * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
27  * temporarily when the library thinks that certain allocations should not be
28  * checked (e.g. the data structures used for memory checking).  It is not
29  * suitable as an initial state: the library will unexpectedly enable memory
30  * checking when it executes one of those sections that want to disable
31  * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
32  * no sense whatsoever.
33  */
34 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
35 static int mh_mode = CRYPTO_MEM_CHECK_OFF;
36 #endif
37
38 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
39 static unsigned long order = 0; /* number of memory requests */
40
41 /*-
42  * For application-defined information (static C-string `info')
43  * to be displayed in memory leak list.
44  * Each thread has its own stack.  For applications, there is
45  *   OPENSSL_mem_debug_push("...")     to push an entry,
46  *   OPENSSL_mem_debug_pop()     to pop an entry,
47  */
48 struct app_mem_info_st {
49     CRYPTO_THREAD_ID threadid;
50     const char *file;
51     int line;
52     const char *info;
53     struct app_mem_info_st *next; /* tail of thread's stack */
54     int references;
55 };
56
57 static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT;
58 static CRYPTO_RWLOCK *malloc_lock = NULL;
59 static CRYPTO_RWLOCK *long_malloc_lock = NULL;
60 static CRYPTO_THREAD_LOCAL appinfokey;
61
62 /* memory-block description */
63 struct mem_st {
64     void *addr;
65     int num;
66     const char *file;
67     int line;
68     CRYPTO_THREAD_ID threadid;
69     unsigned long order;
70     time_t time;
71     APP_INFO *app_info;
72 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
73     void *array[30];
74     size_t array_siz;
75 #endif
76 };
77
78 static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as
79                                   * key); access requires MALLOC2 lock */
80
81 /* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
82 static unsigned int num_disable = 0;
83
84 /*
85  * Valid iff num_disable > 0.  long_malloc_lock is locked exactly in this
86  * case (by the thread named in disabling_thread).
87  */
88 static CRYPTO_THREAD_ID disabling_threadid;
89
90 static void do_memdbg_init(void)
91 {
92     malloc_lock = CRYPTO_THREAD_lock_new();
93     long_malloc_lock = CRYPTO_THREAD_lock_new();
94     CRYPTO_THREAD_init_local(&appinfokey, NULL);
95 }
96
97 static void app_info_free(APP_INFO *inf)
98 {
99     if (!inf)
100         return;
101     if (--(inf->references) <= 0) {
102         app_info_free(inf->next);
103         OPENSSL_free(inf);
104     }
105 }
106 #endif
107
108 int CRYPTO_mem_ctrl(int mode)
109 {
110 #ifdef OPENSSL_NO_CRYPTO_MDEBUG
111     return mode - mode;
112 #else
113     int ret = mh_mode;
114
115     if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
116         return -1;
117
118     CRYPTO_THREAD_write_lock(malloc_lock);
119     switch (mode) {
120     default:
121         break;
122
123     case CRYPTO_MEM_CHECK_ON:
124         mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
125         num_disable = 0;
126         break;
127
128     case CRYPTO_MEM_CHECK_OFF:
129         mh_mode = 0;
130         num_disable = 0;
131         break;
132
133     /* switch off temporarily (for library-internal use): */
134     case CRYPTO_MEM_CHECK_DISABLE:
135         if (mh_mode & CRYPTO_MEM_CHECK_ON) {
136             CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
137             /* see if we don't have long_malloc_lock already */
138             if (!num_disable
139                 || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) {
140                 /*
141                  * Long-time lock long_malloc_lock must not be claimed
142                  * while we're holding malloc_lock, or we'll deadlock
143                  * if somebody else holds long_malloc_lock (and cannot
144                  * release it because we block entry to this function). Give
145                  * them a chance, first, and then claim the locks in
146                  * appropriate order (long-time lock first).
147                  */
148                 CRYPTO_THREAD_unlock(malloc_lock);
149                 /*
150                  * Note that after we have waited for long_malloc_lock and
151                  * malloc_lock, we'll still be in the right "case" and
152                  * "if" branch because MemCheck_start and MemCheck_stop may
153                  * never be used while there are multiple OpenSSL threads.
154                  */
155                 CRYPTO_THREAD_write_lock(long_malloc_lock);
156                 CRYPTO_THREAD_write_lock(malloc_lock);
157                 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
158                 disabling_threadid = cur;
159             }
160             num_disable++;
161         }
162         break;
163
164     case CRYPTO_MEM_CHECK_ENABLE:
165         if (mh_mode & CRYPTO_MEM_CHECK_ON) {
166             if (num_disable) {  /* always true, or something is going wrong */
167                 num_disable--;
168                 if (num_disable == 0) {
169                     mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
170                     CRYPTO_THREAD_unlock(long_malloc_lock);
171                 }
172             }
173         }
174         break;
175     }
176     CRYPTO_THREAD_unlock(malloc_lock);
177     return (ret);
178 #endif
179 }
180
181 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
182
183 static int mem_check_on(void)
184 {
185     int ret = 0;
186     CRYPTO_THREAD_ID cur;
187
188     if (mh_mode & CRYPTO_MEM_CHECK_ON) {
189         if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
190             return 0;
191
192         cur = CRYPTO_THREAD_get_current_id();
193         CRYPTO_THREAD_read_lock(malloc_lock);
194
195         ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
196             || !CRYPTO_THREAD_compare_id(disabling_threadid, cur);
197
198         CRYPTO_THREAD_unlock(malloc_lock);
199     }
200     return (ret);
201 }
202
203 static int mem_cmp(const MEM *a, const MEM *b)
204 {
205 #ifdef _WIN64
206     const char *ap = (const char *)a->addr, *bp = (const char *)b->addr;
207     if (ap == bp)
208         return 0;
209     else if (ap > bp)
210         return 1;
211     else
212         return -1;
213 #else
214     return (const char *)a->addr - (const char *)b->addr;
215 #endif
216 }
217
218 static unsigned long mem_hash(const MEM *a)
219 {
220     size_t ret;
221
222     ret = (size_t)a->addr;
223
224     ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
225     return (ret);
226 }
227
228 /* returns 1 if there was an info to pop, 0 if the stack was empty. */
229 static int pop_info(void)
230 {
231     APP_INFO *current = NULL;
232
233     if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
234         return 0;
235
236     current = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
237     if (current != NULL) {
238         APP_INFO *next = current->next;
239
240         if (next != NULL) {
241             next->references++;
242             CRYPTO_THREAD_set_local(&appinfokey, next);
243         } else {
244             CRYPTO_THREAD_set_local(&appinfokey, NULL);
245         }
246         if (--(current->references) <= 0) {
247             current->next = NULL;
248             if (next != NULL)
249                 next->references--;
250             OPENSSL_free(current);
251         }
252         return 1;
253     }
254     return 0;
255 }
256
257 int CRYPTO_mem_debug_push(const char *info, const char *file, int line)
258 {
259     APP_INFO *ami, *amim;
260     int ret = 0;
261
262     if (mem_check_on()) {
263         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
264
265         if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
266             || (ami = OPENSSL_malloc(sizeof(*ami))) == NULL)
267             goto err;
268
269         ami->threadid = CRYPTO_THREAD_get_current_id();
270         ami->file = file;
271         ami->line = line;
272         ami->info = info;
273         ami->references = 1;
274         ami->next = NULL;
275
276         amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
277         CRYPTO_THREAD_set_local(&appinfokey, ami);
278
279         if (amim != NULL)
280             ami->next = amim;
281         ret = 1;
282  err:
283         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
284     }
285
286     return (ret);
287 }
288
289 int CRYPTO_mem_debug_pop(void)
290 {
291     int ret = 0;
292
293     if (mem_check_on()) {
294         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
295         ret = pop_info();
296         CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
297     }
298     return (ret);
299 }
300
301 static unsigned long break_order_num = 0;
302
303 void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p,
304                              const char *file, int line)
305 {
306     MEM *m, *mm;
307     APP_INFO *amim;
308
309     switch (before_p & 127) {
310     case 0:
311         break;
312     case 1:
313         if (addr == NULL)
314             break;
315
316         if (mem_check_on()) {
317             CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
318
319             if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
320                 || (m = OPENSSL_malloc(sizeof(*m))) == NULL) {
321                 OPENSSL_free(addr);
322                 CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
323                 return;
324             }
325             if (mh == NULL) {
326                 if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) {
327                     OPENSSL_free(addr);
328                     OPENSSL_free(m);
329                     addr = NULL;
330                     goto err;
331                 }
332             }
333
334             m->addr = addr;
335             m->file = file;
336             m->line = line;
337             m->num = num;
338             m->threadid = CRYPTO_THREAD_get_current_id();
339
340             if (order == break_order_num) {
341                 /* BREAK HERE */
342                 m->order = order;
343             }
344             m->order = order++;
345 # ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
346             m->array_siz = backtrace(m->array, OSSL_NELEM(m->array));
347 # endif
348             m->time = time(NULL);
349
350             amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
351             m->app_info = amim;
352             if (amim != NULL)
353                 amim->references++;
354
355             if ((mm = lh_MEM_insert(mh, m)) != NULL) {
356                 /* Not good, but don't sweat it */
357                 if (mm->app_info != NULL) {
358                     mm->app_info->references--;
359                 }
360                 OPENSSL_free(mm);
361             }
362  err:
363             CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
364         }
365         break;
366     }
367     return;
368 }
369
370 void CRYPTO_mem_debug_free(void *addr, int before_p,
371         const char *file, int line)
372 {
373     MEM m, *mp;
374
375     switch (before_p) {
376     case 0:
377         if (addr == NULL)
378             break;
379
380         if (mem_check_on() && (mh != NULL)) {
381             CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
382
383             m.addr = addr;
384             mp = lh_MEM_delete(mh, &m);
385             if (mp != NULL) {
386                 app_info_free(mp->app_info);
387                 OPENSSL_free(mp);
388             }
389
390             CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
391         }
392         break;
393     case 1:
394         break;
395     }
396 }
397
398 void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num,
399                               int before_p, const char *file, int line)
400 {
401     MEM m, *mp;
402
403     switch (before_p) {
404     case 0:
405         break;
406     case 1:
407         if (addr2 == NULL)
408             break;
409
410         if (addr1 == NULL) {
411             CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line);
412             break;
413         }
414
415         if (mem_check_on()) {
416             CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
417
418             m.addr = addr1;
419             mp = lh_MEM_delete(mh, &m);
420             if (mp != NULL) {
421                 mp->addr = addr2;
422                 mp->num = num;
423 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
424                 mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array));
425 #endif
426                 (void)lh_MEM_insert(mh, mp);
427             }
428
429             CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
430         }
431         break;
432     }
433     return;
434 }
435
436 typedef struct mem_leak_st {
437     BIO *bio;
438     int chunks;
439     long bytes;
440 } MEM_LEAK;
441
442 static void print_leak(const MEM *m, MEM_LEAK *l)
443 {
444     char buf[1024];
445     char *bufp = buf;
446     APP_INFO *amip;
447     int ami_cnt;
448     struct tm *lcl = NULL;
449     /*
450      * Convert between CRYPTO_THREAD_ID (which could be anything at all) and
451      * a long. This may not be meaningful depending on what CRYPTO_THREAD_ID is
452      * but hopefully should give something sensible on most platforms
453      */
454     union {
455         CRYPTO_THREAD_ID tid;
456         unsigned long ltid;
457     } tid;
458     CRYPTO_THREAD_ID ti;
459
460 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
461
462     lcl = localtime(&m->time);
463     BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
464                  lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
465     bufp += strlen(bufp);
466
467     BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
468                  m->order, m->file, m->line);
469     bufp += strlen(bufp);
470
471     tid.ltid = 0;
472     tid.tid = m->threadid;
473     BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", tid.ltid);
474     bufp += strlen(bufp);
475
476     BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%p\n",
477                  m->num, m->addr);
478     bufp += strlen(bufp);
479
480     BIO_puts(l->bio, buf);
481
482     l->chunks++;
483     l->bytes += m->num;
484
485     amip = m->app_info;
486     ami_cnt = 0;
487
488     if (amip) {
489         ti = amip->threadid;
490
491         do {
492             int buf_len;
493             int info_len;
494
495             ami_cnt++;
496             memset(buf, '>', ami_cnt);
497             tid.ltid = 0;
498             tid.tid = amip->threadid;
499             BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
500                          " thread=%lu, file=%s, line=%d, info=\"",
501                          tid.ltid, amip->file,
502                          amip->line);
503             buf_len = strlen(buf);
504             info_len = strlen(amip->info);
505             if (128 - buf_len - 3 < info_len) {
506                 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
507                 buf_len = 128 - 3;
508             } else {
509                 OPENSSL_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
510                 buf_len = strlen(buf);
511             }
512             BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
513
514             BIO_puts(l->bio, buf);
515
516             amip = amip->next;
517         }
518         while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti));
519     }
520
521 #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
522     {
523         size_t i;
524         char **strings = backtrace_symbols(m->array, m->array_siz);
525
526         for (i = 0; i < m->array_siz; i++)
527             fprintf(stderr, "##> %s\n", strings[i]);
528         free(strings);
529     }
530 #endif
531 }
532
533 IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK);
534
535 int CRYPTO_mem_leaks(BIO *b)
536 {
537     MEM_LEAK ml;
538
539     /*
540      * OPENSSL_cleanup() will free the ex_data locks so we can't have any
541      * ex_data hanging around
542      */
543     bio_free_ex_data(b);
544
545     /* Ensure all resources are released */
546     OPENSSL_cleanup();
547
548     if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
549         return -1;
550
551     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
552
553     ml.bio = b;
554     ml.bytes = 0;
555     ml.chunks = 0;
556     if (mh != NULL)
557         lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml);
558
559     if (ml.chunks != 0) {
560         BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks);
561     } else {
562         /*
563          * Make sure that, if we found no leaks, memory-leak debugging itself
564          * does not introduce memory leaks (which might irritate external
565          * debugging tools). (When someone enables leak checking, but does not
566          * call this function, we declare it to be their fault.)
567          */
568         int old_mh_mode;
569
570         CRYPTO_THREAD_write_lock(malloc_lock);
571
572         /*
573          * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses
574          * mem_check_on
575          */
576         old_mh_mode = mh_mode;
577         mh_mode = CRYPTO_MEM_CHECK_OFF;
578
579         lh_MEM_free(mh);
580         mh = NULL;
581
582         mh_mode = old_mh_mode;
583         CRYPTO_THREAD_unlock(malloc_lock);
584     }
585     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
586
587     /* Clean up locks etc */
588     CRYPTO_THREAD_cleanup_local(&appinfokey);
589     CRYPTO_THREAD_lock_free(malloc_lock);
590     CRYPTO_THREAD_lock_free(long_malloc_lock);
591     malloc_lock = NULL;
592     long_malloc_lock = NULL;
593
594     return ml.chunks == 0 ? 1 : 0;
595 }
596
597 # ifndef OPENSSL_NO_STDIO
598 int CRYPTO_mem_leaks_fp(FILE *fp)
599 {
600     BIO *b;
601     int ret;
602
603     /*
604      * Need to turn off memory checking when allocated BIOs ... especially as
605      * we're creating them at a time when we're trying to check we've not
606      * left anything un-free()'d!!
607      */
608     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
609     b = BIO_new(BIO_s_file());
610     CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
611     if (b == NULL)
612         return -1;
613     BIO_set_fp(b, fp, BIO_NOCLOSE);
614     ret = CRYPTO_mem_leaks(b);
615     BIO_free(b);
616     return ret;
617 }
618 # endif
619
620 #endif