diff options
Diffstat (limited to 'src/lib/libcrypto/mem_dbg.c')
| -rw-r--r-- | src/lib/libcrypto/mem_dbg.c | 98 | 
1 files changed, 62 insertions, 36 deletions
| diff --git a/src/lib/libcrypto/mem_dbg.c b/src/lib/libcrypto/mem_dbg.c index 866c53e73a..ef19d8f844 100644 --- a/src/lib/libcrypto/mem_dbg.c +++ b/src/lib/libcrypto/mem_dbg.c | |||
| @@ -81,7 +81,8 @@ static int mh_mode=CRYPTO_MEM_CHECK_OFF; | |||
| 81 | */ | 81 | */ | 
| 82 | 82 | ||
| 83 | static unsigned long order = 0; /* number of memory requests */ | 83 | static unsigned long order = 0; /* number of memory requests */ | 
| 84 | static LHASH *mh=NULL; /* hash-table of memory requests (address as key) */ | 84 | static LHASH *mh=NULL; /* hash-table of memory requests (address as key); | 
| 85 | * access requires MALLOC2 lock */ | ||
| 85 | 86 | ||
| 86 | 87 | ||
| 87 | typedef struct app_mem_info_st | 88 | typedef struct app_mem_info_st | 
| @@ -103,7 +104,8 @@ typedef struct app_mem_info_st | |||
| 103 | 104 | ||
| 104 | static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's | 105 | static LHASH *amih=NULL; /* hash-table with those app_mem_info_st's | 
| 105 | * that are at the top of their thread's stack | 106 | * that are at the top of their thread's stack | 
| 106 | * (with `thread' as key) */ | 107 | * (with `thread' as key); | 
| 108 | * access requires MALLOC2 lock */ | ||
| 107 | 109 | ||
| 108 | typedef struct mem_st | 110 | typedef struct mem_st | 
| 109 | /* memory-block description */ | 111 | /* memory-block description */ | 
| @@ -128,7 +130,15 @@ static long options = /* extra information to be recorded */ | |||
| 128 | 0; | 130 | 0; | 
| 129 | 131 | ||
| 130 | 132 | ||
| 131 | static unsigned long disabling_thread = 0; | 133 | static unsigned int num_disable = 0; /* num_disable > 0 | 
| 134 | * iff | ||
| 135 | * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) | ||
| 136 | */ | ||
| 137 | static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0. | ||
| 138 | * CRYPTO_LOCK_MALLOC2 is locked | ||
| 139 | * exactly in this case (by the | ||
| 140 | * thread named in disabling_thread). | ||
| 141 | */ | ||
| 132 | 142 | ||
| 133 | int CRYPTO_mem_ctrl(int mode) | 143 | int CRYPTO_mem_ctrl(int mode) | 
| 134 | { | 144 | { | 
| @@ -137,22 +147,23 @@ int CRYPTO_mem_ctrl(int mode) | |||
| 137 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 147 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 
| 138 | switch (mode) | 148 | switch (mode) | 
| 139 | { | 149 | { | 
| 140 | /* for applications: */ | 150 | /* for applications (not to be called while multiple threads | 
| 151 | * use the library): */ | ||
| 141 | case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */ | 152 | case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */ | 
| 142 | mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE; | 153 | mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE; | 
| 143 | disabling_thread = 0; | 154 | num_disable = 0; | 
| 144 | break; | 155 | break; | 
| 145 | case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */ | 156 | case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */ | 
| 146 | mh_mode = 0; | 157 | mh_mode = 0; | 
| 147 | disabling_thread = 0; | 158 | num_disable = 0; /* should be true *before* MemCheck_stop is used, | 
| 159 | or there'll be a lot of confusion */ | ||
| 148 | break; | 160 | break; | 
| 149 | 161 | ||
| 150 | /* switch off temporarily (for library-internal use): */ | 162 | /* switch off temporarily (for library-internal use): */ | 
| 151 | case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ | 163 | case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */ | 
| 152 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 164 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 
| 153 | { | 165 | { | 
| 154 | mh_mode&= ~CRYPTO_MEM_CHECK_ENABLE; | 166 | if (!num_disable || (disabling_thread != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */ | 
| 155 | if (disabling_thread != CRYPTO_thread_id()) /* otherwise we already have the MALLOC2 lock */ | ||
| 156 | { | 167 | { | 
| 157 | /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while | 168 | /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while | 
| 158 | * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if | 169 | * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if | 
| @@ -169,18 +180,23 @@ int CRYPTO_mem_ctrl(int mode) | |||
| 169 | * OpenSSL threads. */ | 180 | * OpenSSL threads. */ | 
| 170 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); | 181 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2); | 
| 171 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 182 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 
| 183 | mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; | ||
| 172 | disabling_thread=CRYPTO_thread_id(); | 184 | disabling_thread=CRYPTO_thread_id(); | 
| 173 | } | 185 | } | 
| 186 | num_disable++; | ||
| 174 | } | 187 | } | 
| 175 | break; | 188 | break; | 
| 176 | case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */ | 189 | case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */ | 
| 177 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 190 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 
| 178 | { | 191 | { | 
| 179 | mh_mode|=CRYPTO_MEM_CHECK_ENABLE; | 192 | if (num_disable) /* always true, or something is going wrong */ | 
| 180 | if (disabling_thread != 0) | ||
| 181 | { | 193 | { | 
| 182 | disabling_thread=0; | 194 | num_disable--; | 
| 183 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); | 195 | if (num_disable == 0) | 
| 196 | { | ||
| 197 | mh_mode|=CRYPTO_MEM_CHECK_ENABLE; | ||
| 198 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2); | ||
| 199 | } | ||
| 184 | } | 200 | } | 
| 185 | } | 201 | } | 
| 186 | break; | 202 | break; | 
| @@ -198,12 +214,12 @@ int CRYPTO_is_mem_check_on(void) | |||
| 198 | 214 | ||
| 199 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 215 | if (mh_mode & CRYPTO_MEM_CHECK_ON) | 
| 200 | { | 216 | { | 
| 201 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 217 | CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); | 
| 202 | 218 | ||
| 203 | ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) | 219 | ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) | 
| 204 | && disabling_thread != CRYPTO_thread_id(); | 220 | || (disabling_thread != CRYPTO_thread_id()); | 
| 205 | 221 | ||
| 206 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | 222 | CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); | 
| 207 | } | 223 | } | 
| 208 | return(ret); | 224 | return(ret); | 
| 209 | } | 225 | } | 
| @@ -293,7 +309,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) | |||
| 293 | 309 | ||
| 294 | if (is_MemCheck_on()) | 310 | if (is_MemCheck_on()) | 
| 295 | { | 311 | { | 
| 296 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | 312 | MemCheck_off(); /* obtain MALLOC2 lock */ | 
| 297 | 313 | ||
| 298 | if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) | 314 | if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) | 
| 299 | { | 315 | { | 
| @@ -330,7 +346,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) | |||
| 330 | ami->next=amim; | 346 | ami->next=amim; | 
| 331 | } | 347 | } | 
| 332 | err: | 348 | err: | 
| 333 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 349 | MemCheck_on(); /* release MALLOC2 lock */ | 
| 334 | } | 350 | } | 
| 335 | 351 | ||
| 336 | return(ret); | 352 | return(ret); | 
| @@ -342,11 +358,11 @@ int CRYPTO_pop_info(void) | |||
| 342 | 358 | ||
| 343 | if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */ | 359 | if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */ | 
| 344 | { | 360 | { | 
| 345 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | 361 | MemCheck_off(); /* obtain MALLOC2 lock */ | 
| 346 | 362 | ||
| 347 | ret=(pop_info() != NULL); | 363 | ret=(pop_info() != NULL); | 
| 348 | 364 | ||
| 349 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 365 | MemCheck_on(); /* release MALLOC2 lock */ | 
| 350 | } | 366 | } | 
| 351 | return(ret); | 367 | return(ret); | 
| 352 | } | 368 | } | 
| @@ -357,12 +373,12 @@ int CRYPTO_remove_all_info(void) | |||
| 357 | 373 | ||
| 358 | if (is_MemCheck_on()) /* _must_ be true */ | 374 | if (is_MemCheck_on()) /* _must_ be true */ | 
| 359 | { | 375 | { | 
| 360 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | 376 | MemCheck_off(); /* obtain MALLOC2 lock */ | 
| 361 | 377 | ||
| 362 | while(pop_info() != NULL) | 378 | while(pop_info() != NULL) | 
| 363 | ret++; | 379 | ret++; | 
| 364 | 380 | ||
| 365 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 381 | MemCheck_on(); /* release MALLOC2 lock */ | 
| 366 | } | 382 | } | 
| 367 | return(ret); | 383 | return(ret); | 
| 368 | } | 384 | } | 
| @@ -385,11 +401,12 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, | |||
| 385 | 401 | ||
| 386 | if (is_MemCheck_on()) | 402 | if (is_MemCheck_on()) | 
| 387 | { | 403 | { | 
| 388 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | 404 | MemCheck_off(); /* make sure we hold MALLOC2 lock */ | 
| 389 | if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) | 405 | if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) | 
| 390 | { | 406 | { | 
| 391 | OPENSSL_free(addr); | 407 | OPENSSL_free(addr); | 
| 392 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 408 | MemCheck_on(); /* release MALLOC2 lock | 
| 409 | * if num_disabled drops to 0 */ | ||
| 393 | return; | 410 | return; | 
| 394 | } | 411 | } | 
| 395 | if (mh == NULL) | 412 | if (mh == NULL) | 
| @@ -448,7 +465,8 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, | |||
| 448 | OPENSSL_free(mm); | 465 | OPENSSL_free(mm); | 
| 449 | } | 466 | } | 
| 450 | err: | 467 | err: | 
| 451 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 468 | MemCheck_on(); /* release MALLOC2 lock | 
| 469 | * if num_disabled drops to 0 */ | ||
| 452 | } | 470 | } | 
| 453 | break; | 471 | break; | 
| 454 | } | 472 | } | 
| @@ -467,7 +485,7 @@ void CRYPTO_dbg_free(void *addr, int before_p) | |||
| 467 | 485 | ||
| 468 | if (is_MemCheck_on() && (mh != NULL)) | 486 | if (is_MemCheck_on() && (mh != NULL)) | 
| 469 | { | 487 | { | 
| 470 | MemCheck_off(); | 488 | MemCheck_off(); /* make sure we hold MALLOC2 lock */ | 
| 471 | 489 | ||
| 472 | m.addr=addr; | 490 | m.addr=addr; | 
| 473 | mp=(MEM *)lh_delete(mh,(char *)&m); | 491 | mp=(MEM *)lh_delete(mh,(char *)&m); | 
| @@ -484,7 +502,8 @@ void CRYPTO_dbg_free(void *addr, int before_p) | |||
| 484 | OPENSSL_free(mp); | 502 | OPENSSL_free(mp); | 
| 485 | } | 503 | } | 
| 486 | 504 | ||
| 487 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 505 | MemCheck_on(); /* release MALLOC2 lock | 
| 506 | * if num_disabled drops to 0 */ | ||
| 488 | } | 507 | } | 
| 489 | break; | 508 | break; | 
| 490 | case 1: | 509 | case 1: | 
| @@ -518,7 +537,7 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, | |||
| 518 | 537 | ||
| 519 | if (is_MemCheck_on()) | 538 | if (is_MemCheck_on()) | 
| 520 | { | 539 | { | 
| 521 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | 540 | MemCheck_off(); /* make sure we hold MALLOC2 lock */ | 
| 522 | 541 | ||
| 523 | m.addr=addr1; | 542 | m.addr=addr1; | 
| 524 | mp=(MEM *)lh_delete(mh,(char *)&m); | 543 | mp=(MEM *)lh_delete(mh,(char *)&m); | 
| @@ -535,7 +554,8 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, | |||
| 535 | lh_insert(mh,(char *)mp); | 554 | lh_insert(mh,(char *)mp); | 
| 536 | } | 555 | } | 
| 537 | 556 | ||
| 538 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 557 | MemCheck_on(); /* release MALLOC2 lock | 
| 558 | * if num_disabled drops to 0 */ | ||
| 539 | } | 559 | } | 
| 540 | break; | 560 | break; | 
| 541 | } | 561 | } | 
| @@ -642,10 +662,12 @@ void CRYPTO_mem_leaks(BIO *b) | |||
| 642 | 662 | ||
| 643 | if (mh == NULL && amih == NULL) | 663 | if (mh == NULL && amih == NULL) | 
| 644 | return; | 664 | return; | 
| 665 | |||
| 666 | MemCheck_off(); /* obtain MALLOC2 lock */ | ||
| 667 | |||
| 645 | ml.bio=b; | 668 | ml.bio=b; | 
| 646 | ml.bytes=0; | 669 | ml.bytes=0; | 
| 647 | ml.chunks=0; | 670 | ml.chunks=0; | 
| 648 | MemCheck_off(); /* obtains CRYPTO_LOCK_MALLOC2 */ | ||
| 649 | if (mh != NULL) | 671 | if (mh != NULL) | 
| 650 | lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml); | 672 | lh_doall_arg(mh,(void (*)())print_leak,(char *)&ml); | 
| 651 | if (ml.chunks != 0) | 673 | if (ml.chunks != 0) | 
| @@ -671,7 +693,15 @@ void CRYPTO_mem_leaks(BIO *b) | |||
| 671 | * void_fn_to_char kludge in CRYPTO_mem_leaks_cb. | 693 | * void_fn_to_char kludge in CRYPTO_mem_leaks_cb. | 
| 672 | * Otherwise the code police will come and get us.) | 694 | * Otherwise the code police will come and get us.) | 
| 673 | */ | 695 | */ | 
| 696 | int old_mh_mode; | ||
| 697 | |||
| 674 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 698 | CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | 
| 699 | |||
| 700 | /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(), | ||
| 701 | * which uses CRYPTO_is_mem_check_on */ | ||
| 702 | old_mh_mode = mh_mode; | ||
| 703 | mh_mode = CRYPTO_MEM_CHECK_OFF; | ||
| 704 | |||
| 675 | if (mh != NULL) | 705 | if (mh != NULL) | 
| 676 | { | 706 | { | 
| 677 | lh_free(mh); | 707 | lh_free(mh); | 
| @@ -685,15 +715,11 @@ void CRYPTO_mem_leaks(BIO *b) | |||
| 685 | amih = NULL; | 715 | amih = NULL; | 
| 686 | } | 716 | } | 
| 687 | } | 717 | } | 
| 718 | |||
| 719 | mh_mode = old_mh_mode; | ||
| 688 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | 720 | CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | 
| 689 | } | 721 | } | 
| 690 | MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | 722 | MemCheck_on(); /* release MALLOC2 lock */ | 
| 691 | |||
| 692 | #if 0 | ||
| 693 | lh_stats_bio(mh,b); | ||
| 694 | lh_node_stats_bio(mh,b); | ||
| 695 | lh_node_usage_stats_bio(mh,b); | ||
| 696 | #endif | ||
| 697 | } | 723 | } | 
| 698 | 724 | ||
| 699 | #ifndef NO_FP_API | 725 | #ifndef NO_FP_API | 
