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