diff options
Diffstat (limited to 'src/lib/libssl/src/crypto/mem_dbg.c')
-rw-r--r-- | src/lib/libssl/src/crypto/mem_dbg.c | 98 |
1 files changed, 62 insertions, 36 deletions
diff --git a/src/lib/libssl/src/crypto/mem_dbg.c b/src/lib/libssl/src/crypto/mem_dbg.c index 866c53e73a..ef19d8f844 100644 --- a/src/lib/libssl/src/crypto/mem_dbg.c +++ b/src/lib/libssl/src/crypto/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 |