Print this page
4853 illumos-gate is not lint-clean when built with openssl 1.0
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/lib/openssl/libsunw_crypto/mem_dbg.c
+++ new/usr/src/lib/openssl/libsunw_crypto/mem_dbg.c
1 1 /* crypto/mem_dbg.c */
2 2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3 3 * All rights reserved.
4 4 *
5 5 * This package is an SSL implementation written
6 6 * by Eric Young (eay@cryptsoft.com).
7 7 * The implementation was written so as to conform with Netscapes SSL.
8 8 *
9 9 * This library is free for commercial and non-commercial use as long as
10 10 * the following conditions are aheared to. The following conditions
11 11 * apply to all code found in this distribution, be it the RC4, RSA,
12 12 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
13 13 * included with this distribution is covered by the same copyright terms
14 14 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15 15 *
16 16 * Copyright remains Eric Young's, and as such any Copyright notices in
17 17 * the code are not to be removed.
18 18 * If this package is used in a product, Eric Young should be given attribution
19 19 * as the author of the parts of the library used.
20 20 * This can be in the form of a textual message at program startup or
21 21 * in documentation (online or textual) provided with the package.
22 22 *
23 23 * Redistribution and use in source and binary forms, with or without
24 24 * modification, are permitted provided that the following conditions
25 25 * are met:
26 26 * 1. Redistributions of source code must retain the copyright
27 27 * notice, this list of conditions and the following disclaimer.
28 28 * 2. Redistributions in binary form must reproduce the above copyright
29 29 * notice, this list of conditions and the following disclaimer in the
30 30 * documentation and/or other materials provided with the distribution.
31 31 * 3. All advertising materials mentioning features or use of this software
32 32 * must display the following acknowledgement:
33 33 * "This product includes cryptographic software written by
34 34 * Eric Young (eay@cryptsoft.com)"
35 35 * The word 'cryptographic' can be left out if the rouines from the library
36 36 * being used are not cryptographic related :-).
37 37 * 4. If you include any Windows specific code (or a derivative thereof) from
38 38 * the apps directory (application code) you must include an acknowledgement:
39 39 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40 40 *
41 41 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42 42 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43 43 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44 44 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45 45 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46 46 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47 47 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48 48 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49 49 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50 50 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51 51 * SUCH DAMAGE.
52 52 *
53 53 * The licence and distribution terms for any publically available version or
54 54 * derivative of this code cannot be changed. i.e. this code cannot simply be
55 55 * copied and put under another distribution licence
56 56 * [including the GNU Public Licence.]
57 57 */
58 58 /* ====================================================================
59 59 * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved.
60 60 *
61 61 * Redistribution and use in source and binary forms, with or without
62 62 * modification, are permitted provided that the following conditions
63 63 * are met:
64 64 *
65 65 * 1. Redistributions of source code must retain the above copyright
66 66 * notice, this list of conditions and the following disclaimer.
67 67 *
68 68 * 2. Redistributions in binary form must reproduce the above copyright
69 69 * notice, this list of conditions and the following disclaimer in
70 70 * the documentation and/or other materials provided with the
71 71 * distribution.
72 72 *
73 73 * 3. All advertising materials mentioning features or use of this
74 74 * software must display the following acknowledgment:
75 75 * "This product includes software developed by the OpenSSL Project
76 76 * for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
77 77 *
78 78 * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
79 79 * endorse or promote products derived from this software without
80 80 * prior written permission. For written permission, please contact
81 81 * openssl-core@openssl.org.
82 82 *
83 83 * 5. Products derived from this software may not be called "OpenSSL"
84 84 * nor may "OpenSSL" appear in their names without prior written
85 85 * permission of the OpenSSL Project.
86 86 *
87 87 * 6. Redistributions of any form whatsoever must retain the following
88 88 * acknowledgment:
89 89 * "This product includes software developed by the OpenSSL Project
90 90 * for use in the OpenSSL Toolkit (http://www.openssl.org/)"
91 91 *
92 92 * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
93 93 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
94 94 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
95 95 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR
96 96 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
97 97 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
98 98 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
99 99 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
100 100 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
101 101 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
102 102 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
103 103 * OF THE POSSIBILITY OF SUCH DAMAGE.
104 104 * ====================================================================
↓ open down ↓ |
104 lines elided |
↑ open up ↑ |
105 105 *
106 106 * This product includes cryptographic software written by Eric Young
107 107 * (eay@cryptsoft.com). This product includes software written by Tim
108 108 * Hudson (tjh@cryptsoft.com).
109 109 *
110 110 */
111 111
112 112 #include <stdio.h>
113 113 #include <stdlib.h>
114 114 #include <time.h>
115 -#include "cryptlib.h"
115 +#include <cryptlib.h>
116 116 #include <openssl/crypto.h>
117 117 #include <openssl/buffer.h>
118 118 #include <openssl/bio.h>
119 119 #include <openssl/lhash.h>
120 120
121 121 static int mh_mode=CRYPTO_MEM_CHECK_OFF;
122 122 /* The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE
123 123 * when the application asks for it (usually after library initialisation
124 124 * for which no book-keeping is desired).
125 125 *
126 126 * State CRYPTO_MEM_CHECK_ON exists only temporarily when the library
127 127 * thinks that certain allocations should not be checked (e.g. the data
128 128 * structures used for memory checking). It is not suitable as an initial
129 129 * state: the library will unexpectedly enable memory checking when it
130 130 * executes one of those sections that want to disable checking
131 131 * temporarily.
132 132 *
133 133 * State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes no sense whatsoever.
134 134 */
135 135
136 136 static unsigned long order = 0; /* number of memory requests */
137 137
138 138 DECLARE_LHASH_OF(MEM);
139 139 static LHASH_OF(MEM) *mh=NULL; /* hash-table of memory requests
140 140 * (address as key); access requires
141 141 * MALLOC2 lock */
142 142
143 143
144 144 typedef struct app_mem_info_st
145 145 /* For application-defined information (static C-string `info')
146 146 * to be displayed in memory leak list.
147 147 * Each thread has its own stack. For applications, there is
148 148 * CRYPTO_push_info("...") to push an entry,
149 149 * CRYPTO_pop_info() to pop an entry,
150 150 * CRYPTO_remove_all_info() to pop all entries.
151 151 */
152 152 {
153 153 CRYPTO_THREADID threadid;
154 154 const char *file;
155 155 int line;
156 156 const char *info;
157 157 struct app_mem_info_st *next; /* tail of thread's stack */
158 158 int references;
159 159 } APP_INFO;
160 160
161 161 static void app_info_free(APP_INFO *);
162 162
163 163 DECLARE_LHASH_OF(APP_INFO);
164 164 static LHASH_OF(APP_INFO) *amih=NULL; /* hash-table with those
165 165 * app_mem_info_st's that are at
166 166 * the top of their thread's
167 167 * stack (with `thread' as key);
168 168 * access requires MALLOC2
169 169 * lock */
170 170
171 171 typedef struct mem_st
172 172 /* memory-block description */
173 173 {
174 174 void *addr;
175 175 int num;
176 176 const char *file;
177 177 int line;
178 178 CRYPTO_THREADID threadid;
179 179 unsigned long order;
180 180 time_t time;
181 181 APP_INFO *app_info;
182 182 } MEM;
183 183
184 184 static long options = /* extra information to be recorded */
185 185 #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
186 186 V_CRYPTO_MDEBUG_TIME |
187 187 #endif
188 188 #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
189 189 V_CRYPTO_MDEBUG_THREAD |
190 190 #endif
191 191 0;
192 192
193 193
194 194 static unsigned int num_disable = 0; /* num_disable > 0
195 195 * iff
196 196 * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
197 197 */
198 198
199 199 /* Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this
200 200 * case (by the thread named in disabling_thread).
201 201 */
202 202 static CRYPTO_THREADID disabling_threadid;
203 203
204 204 static void app_info_free(APP_INFO *inf)
205 205 {
206 206 if (--(inf->references) <= 0)
207 207 {
208 208 if (inf->next != NULL)
209 209 {
210 210 app_info_free(inf->next);
211 211 }
212 212 OPENSSL_free(inf);
213 213 }
214 214 }
215 215
216 216 int CRYPTO_mem_ctrl(int mode)
217 217 {
218 218 int ret=mh_mode;
219 219
220 220 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
221 221 switch (mode)
222 222 {
223 223 /* for applications (not to be called while multiple threads
224 224 * use the library): */
225 225 case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
226 226 mh_mode = CRYPTO_MEM_CHECK_ON|CRYPTO_MEM_CHECK_ENABLE;
227 227 num_disable = 0;
228 228 break;
229 229 case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
230 230 mh_mode = 0;
231 231 num_disable = 0; /* should be true *before* MemCheck_stop is used,
232 232 or there'll be a lot of confusion */
233 233 break;
234 234
235 235 /* switch off temporarily (for library-internal use): */
236 236 case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
237 237 if (mh_mode & CRYPTO_MEM_CHECK_ON)
238 238 {
239 239 CRYPTO_THREADID cur;
240 240 CRYPTO_THREADID_current(&cur);
241 241 if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
242 242 {
243 243 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
244 244 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
245 245 * somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot release
246 246 * it because we block entry to this function).
247 247 * Give them a chance, first, and then claim the locks in
248 248 * appropriate order (long-time lock first).
249 249 */
250 250 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
251 251 /* Note that after we have waited for CRYPTO_LOCK_MALLOC2
252 252 * and CRYPTO_LOCK_MALLOC, we'll still be in the right
253 253 * "case" and "if" branch because MemCheck_start and
254 254 * MemCheck_stop may never be used while there are multiple
255 255 * OpenSSL threads. */
256 256 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
257 257 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
258 258 mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
259 259 CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
260 260 }
261 261 num_disable++;
262 262 }
263 263 break;
264 264 case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
265 265 if (mh_mode & CRYPTO_MEM_CHECK_ON)
266 266 {
267 267 if (num_disable) /* always true, or something is going wrong */
268 268 {
269 269 num_disable--;
270 270 if (num_disable == 0)
271 271 {
272 272 mh_mode|=CRYPTO_MEM_CHECK_ENABLE;
273 273 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
274 274 }
275 275 }
276 276 }
277 277 break;
278 278
279 279 default:
280 280 break;
281 281 }
282 282 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
283 283 return(ret);
284 284 }
285 285
286 286 int CRYPTO_is_mem_check_on(void)
287 287 {
288 288 int ret = 0;
289 289
290 290 if (mh_mode & CRYPTO_MEM_CHECK_ON)
291 291 {
292 292 CRYPTO_THREADID cur;
293 293 CRYPTO_THREADID_current(&cur);
294 294 CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
295 295
296 296 ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
297 297 || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
298 298
299 299 CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
300 300 }
301 301 return(ret);
302 302 }
303 303
304 304
305 305 void CRYPTO_dbg_set_options(long bits)
306 306 {
307 307 options = bits;
308 308 }
309 309
310 310 long CRYPTO_dbg_get_options(void)
311 311 {
312 312 return options;
313 313 }
314 314
315 315 static int mem_cmp(const MEM *a, const MEM *b)
316 316 {
317 317 #ifdef _WIN64
318 318 const char *ap=(const char *)a->addr,
319 319 *bp=(const char *)b->addr;
320 320 if (ap==bp) return 0;
321 321 else if (ap>bp) return 1;
322 322 else return -1;
323 323 #else
324 324 return (const char *)a->addr - (const char *)b->addr;
325 325 #endif
326 326 }
327 327 static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
328 328
329 329 static unsigned long mem_hash(const MEM *a)
330 330 {
331 331 unsigned long ret;
332 332
333 333 ret=(unsigned long)a->addr;
334 334
335 335 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
336 336 return(ret);
337 337 }
338 338 static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
339 339
340 340 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
341 341 static int app_info_cmp(const void *a_void, const void *b_void)
342 342 {
343 343 return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
344 344 &((const APP_INFO *)b_void)->threadid);
345 345 }
346 346 static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
347 347
348 348 static unsigned long app_info_hash(const APP_INFO *a)
349 349 {
350 350 unsigned long ret;
351 351
352 352 ret = CRYPTO_THREADID_hash(&a->threadid);
353 353 /* This is left in as a "who am I to question legacy?" measure */
354 354 ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
355 355 return(ret);
356 356 }
357 357 static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
358 358
359 359 static APP_INFO *pop_info(void)
360 360 {
361 361 APP_INFO tmp;
362 362 APP_INFO *ret = NULL;
363 363
364 364 if (amih != NULL)
365 365 {
366 366 CRYPTO_THREADID_current(&tmp.threadid);
367 367 if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
368 368 {
369 369 APP_INFO *next=ret->next;
370 370
371 371 if (next != NULL)
372 372 {
373 373 next->references++;
374 374 (void)lh_APP_INFO_insert(amih,next);
375 375 }
376 376 #ifdef LEVITTE_DEBUG_MEM
377 377 if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
378 378 {
379 379 fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
380 380 CRYPTO_THREADID_hash(&ret->threadid),
381 381 CRYPTO_THREADID_hash(&tmp.threadid));
382 382 abort();
383 383 }
384 384 #endif
385 385 if (--(ret->references) <= 0)
386 386 {
387 387 ret->next = NULL;
388 388 if (next != NULL)
389 389 next->references--;
390 390 OPENSSL_free(ret);
391 391 }
392 392 }
393 393 }
394 394 return(ret);
395 395 }
396 396
397 397 int CRYPTO_push_info_(const char *info, const char *file, int line)
398 398 {
399 399 APP_INFO *ami, *amim;
400 400 int ret=0;
401 401
402 402 if (is_MemCheck_on())
403 403 {
404 404 MemCheck_off(); /* obtain MALLOC2 lock */
405 405
406 406 if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL)
407 407 {
408 408 ret=0;
409 409 goto err;
410 410 }
411 411 if (amih == NULL)
412 412 {
413 413 if ((amih=lh_APP_INFO_new()) == NULL)
414 414 {
415 415 OPENSSL_free(ami);
416 416 ret=0;
417 417 goto err;
418 418 }
419 419 }
420 420
421 421 CRYPTO_THREADID_current(&ami->threadid);
422 422 ami->file=file;
423 423 ami->line=line;
424 424 ami->info=info;
425 425 ami->references=1;
426 426 ami->next=NULL;
427 427
428 428 if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
429 429 {
430 430 #ifdef LEVITTE_DEBUG_MEM
431 431 if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
432 432 {
433 433 fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
434 434 CRYPTO_THREADID_hash(&amim->threadid),
435 435 CRYPTO_THREADID_hash(&ami->threadid));
436 436 abort();
437 437 }
438 438 #endif
439 439 ami->next=amim;
440 440 }
441 441 err:
442 442 MemCheck_on(); /* release MALLOC2 lock */
443 443 }
444 444
445 445 return(ret);
446 446 }
447 447
448 448 int CRYPTO_pop_info(void)
449 449 {
450 450 int ret=0;
451 451
452 452 if (is_MemCheck_on()) /* _must_ be true, or something went severely wrong */
453 453 {
454 454 MemCheck_off(); /* obtain MALLOC2 lock */
455 455
456 456 ret=(pop_info() != NULL);
457 457
458 458 MemCheck_on(); /* release MALLOC2 lock */
459 459 }
460 460 return(ret);
461 461 }
462 462
463 463 int CRYPTO_remove_all_info(void)
464 464 {
465 465 int ret=0;
466 466
467 467 if (is_MemCheck_on()) /* _must_ be true */
468 468 {
469 469 MemCheck_off(); /* obtain MALLOC2 lock */
470 470
471 471 while(pop_info() != NULL)
472 472 ret++;
473 473
474 474 MemCheck_on(); /* release MALLOC2 lock */
475 475 }
476 476 return(ret);
477 477 }
478 478
479 479
480 480 static unsigned long break_order_num=0;
481 481 void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
482 482 int before_p)
483 483 {
484 484 MEM *m,*mm;
485 485 APP_INFO tmp,*amim;
486 486
487 487 switch(before_p & 127)
488 488 {
489 489 case 0:
490 490 break;
491 491 case 1:
492 492 if (addr == NULL)
493 493 break;
494 494
495 495 if (is_MemCheck_on())
496 496 {
497 497 MemCheck_off(); /* make sure we hold MALLOC2 lock */
498 498 if ((m=(MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL)
499 499 {
500 500 OPENSSL_free(addr);
501 501 MemCheck_on(); /* release MALLOC2 lock
502 502 * if num_disabled drops to 0 */
503 503 return;
504 504 }
505 505 if (mh == NULL)
506 506 {
507 507 if ((mh=lh_MEM_new()) == NULL)
508 508 {
509 509 OPENSSL_free(addr);
510 510 OPENSSL_free(m);
511 511 addr=NULL;
512 512 goto err;
513 513 }
514 514 }
515 515
516 516 m->addr=addr;
517 517 m->file=file;
518 518 m->line=line;
519 519 m->num=num;
520 520 if (options & V_CRYPTO_MDEBUG_THREAD)
521 521 CRYPTO_THREADID_current(&m->threadid);
522 522 else
523 523 memset(&m->threadid, 0, sizeof(m->threadid));
524 524
525 525 if (order == break_order_num)
526 526 {
527 527 /* BREAK HERE */
528 528 m->order=order;
529 529 }
530 530 m->order=order++;
531 531 #ifdef LEVITTE_DEBUG_MEM
532 532 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
533 533 m->order,
534 534 (before_p & 128) ? '*' : '+',
535 535 m->addr, m->num);
536 536 #endif
537 537 if (options & V_CRYPTO_MDEBUG_TIME)
538 538 m->time=time(NULL);
539 539 else
540 540 m->time=0;
541 541
542 542 CRYPTO_THREADID_current(&tmp.threadid);
543 543 m->app_info=NULL;
544 544 if (amih != NULL
545 545 && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
546 546 {
547 547 m->app_info = amim;
548 548 amim->references++;
549 549 }
550 550
551 551 if ((mm=lh_MEM_insert(mh, m)) != NULL)
552 552 {
553 553 /* Not good, but don't sweat it */
554 554 if (mm->app_info != NULL)
555 555 {
556 556 mm->app_info->references--;
557 557 }
558 558 OPENSSL_free(mm);
559 559 }
560 560 err:
561 561 MemCheck_on(); /* release MALLOC2 lock
562 562 * if num_disabled drops to 0 */
563 563 }
564 564 break;
565 565 }
566 566 return;
567 567 }
568 568
569 569 void CRYPTO_dbg_free(void *addr, int before_p)
570 570 {
571 571 MEM m,*mp;
572 572
573 573 switch(before_p)
574 574 {
575 575 case 0:
576 576 if (addr == NULL)
577 577 break;
578 578
579 579 if (is_MemCheck_on() && (mh != NULL))
580 580 {
581 581 MemCheck_off(); /* make sure we hold MALLOC2 lock */
582 582
583 583 m.addr=addr;
584 584 mp=lh_MEM_delete(mh,&m);
585 585 if (mp != NULL)
586 586 {
587 587 #ifdef LEVITTE_DEBUG_MEM
588 588 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
589 589 mp->order, mp->addr, mp->num);
590 590 #endif
591 591 if (mp->app_info != NULL)
592 592 app_info_free(mp->app_info);
593 593 OPENSSL_free(mp);
594 594 }
595 595
596 596 MemCheck_on(); /* release MALLOC2 lock
597 597 * if num_disabled drops to 0 */
598 598 }
599 599 break;
600 600 case 1:
601 601 break;
602 602 }
603 603 }
604 604
605 605 void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
606 606 const char *file, int line, int before_p)
607 607 {
608 608 MEM m,*mp;
609 609
610 610 #ifdef LEVITTE_DEBUG_MEM
611 611 fprintf(stderr, "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
612 612 addr1, addr2, num, file, line, before_p);
613 613 #endif
614 614
615 615 switch(before_p)
616 616 {
617 617 case 0:
618 618 break;
619 619 case 1:
620 620 if (addr2 == NULL)
621 621 break;
622 622
623 623 if (addr1 == NULL)
624 624 {
625 625 CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
626 626 break;
627 627 }
628 628
629 629 if (is_MemCheck_on())
630 630 {
631 631 MemCheck_off(); /* make sure we hold MALLOC2 lock */
632 632
633 633 m.addr=addr1;
634 634 mp=lh_MEM_delete(mh,&m);
635 635 if (mp != NULL)
636 636 {
637 637 #ifdef LEVITTE_DEBUG_MEM
638 638 fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
639 639 mp->order,
640 640 mp->addr, mp->num,
641 641 addr2, num);
642 642 #endif
643 643 mp->addr=addr2;
644 644 mp->num=num;
645 645 (void)lh_MEM_insert(mh,mp);
646 646 }
647 647
648 648 MemCheck_on(); /* release MALLOC2 lock
649 649 * if num_disabled drops to 0 */
650 650 }
651 651 break;
652 652 }
653 653 return;
654 654 }
655 655
656 656
657 657 typedef struct mem_leak_st
658 658 {
659 659 BIO *bio;
660 660 int chunks;
661 661 long bytes;
662 662 } MEM_LEAK;
663 663
664 664 static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
665 665 {
666 666 char buf[1024];
667 667 char *bufp = buf;
668 668 APP_INFO *amip;
669 669 int ami_cnt;
670 670 struct tm *lcl = NULL;
671 671 CRYPTO_THREADID ti;
672 672
673 673 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
674 674
675 675 if(m->addr == (char *)l->bio)
676 676 return;
677 677
678 678 if (options & V_CRYPTO_MDEBUG_TIME)
679 679 {
680 680 lcl = localtime(&m->time);
681 681
682 682 BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
683 683 lcl->tm_hour,lcl->tm_min,lcl->tm_sec);
684 684 bufp += strlen(bufp);
685 685 }
686 686
687 687 BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
688 688 m->order,m->file,m->line);
689 689 bufp += strlen(bufp);
690 690
691 691 if (options & V_CRYPTO_MDEBUG_THREAD)
692 692 {
693 693 BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
694 694 CRYPTO_THREADID_hash(&m->threadid));
695 695 bufp += strlen(bufp);
696 696 }
697 697
698 698 BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
699 699 m->num,(unsigned long)m->addr);
700 700 bufp += strlen(bufp);
701 701
702 702 BIO_puts(l->bio,buf);
703 703
704 704 l->chunks++;
705 705 l->bytes+=m->num;
706 706
707 707 amip=m->app_info;
708 708 ami_cnt=0;
709 709 if (!amip)
710 710 return;
711 711 CRYPTO_THREADID_cpy(&ti, &amip->threadid);
712 712
713 713 do
714 714 {
715 715 int buf_len;
716 716 int info_len;
717 717
718 718 ami_cnt++;
719 719 memset(buf,'>',ami_cnt);
720 720 BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
721 721 " thread=%lu, file=%s, line=%d, info=\"",
722 722 CRYPTO_THREADID_hash(&amip->threadid), amip->file,
723 723 amip->line);
724 724 buf_len=strlen(buf);
725 725 info_len=strlen(amip->info);
726 726 if (128 - buf_len - 3 < info_len)
727 727 {
728 728 memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
729 729 buf_len = 128 - 3;
730 730 }
731 731 else
732 732 {
733 733 BUF_strlcpy(buf + buf_len, amip->info,
734 734 sizeof buf - buf_len);
735 735 buf_len = strlen(buf);
736 736 }
737 737 BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
738 738
739 739 BIO_puts(l->bio,buf);
740 740
741 741 amip = amip->next;
742 742 }
743 743 while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
744 744
745 745 #ifdef LEVITTE_DEBUG_MEM
746 746 if (amip)
747 747 {
748 748 fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
749 749 abort();
750 750 }
751 751 #endif
752 752 }
753 753
754 754 static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
755 755
756 756 void CRYPTO_mem_leaks(BIO *b)
757 757 {
758 758 MEM_LEAK ml;
759 759
760 760 if (mh == NULL && amih == NULL)
761 761 return;
762 762
763 763 MemCheck_off(); /* obtain MALLOC2 lock */
764 764
765 765 ml.bio=b;
766 766 ml.bytes=0;
767 767 ml.chunks=0;
768 768 if (mh != NULL)
769 769 lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK,
770 770 &ml);
771 771 if (ml.chunks != 0)
772 772 {
773 773 BIO_printf(b,"%ld bytes leaked in %d chunks\n",
774 774 ml.bytes,ml.chunks);
775 775 #ifdef CRYPTO_MDEBUG_ABORT
776 776 abort();
777 777 #endif
778 778 }
779 779 else
780 780 {
781 781 /* Make sure that, if we found no leaks, memory-leak debugging itself
782 782 * does not introduce memory leaks (which might irritate
783 783 * external debugging tools).
784 784 * (When someone enables leak checking, but does not call
785 785 * this function, we declare it to be their fault.)
786 786 *
787 787 * XXX This should be in CRYPTO_mem_leaks_cb,
788 788 * and CRYPTO_mem_leaks should be implemented by
789 789 * using CRYPTO_mem_leaks_cb.
790 790 * (Also there should be a variant of lh_doall_arg
791 791 * that takes a function pointer instead of a void *;
792 792 * this would obviate the ugly and illegal
793 793 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb.
794 794 * Otherwise the code police will come and get us.)
795 795 */
796 796 int old_mh_mode;
797 797
798 798 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
799 799
800 800 /* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
801 801 * which uses CRYPTO_is_mem_check_on */
802 802 old_mh_mode = mh_mode;
803 803 mh_mode = CRYPTO_MEM_CHECK_OFF;
804 804
805 805 if (mh != NULL)
806 806 {
807 807 lh_MEM_free(mh);
808 808 mh = NULL;
809 809 }
810 810 if (amih != NULL)
811 811 {
812 812 if (lh_APP_INFO_num_items(amih) == 0)
813 813 {
814 814 lh_APP_INFO_free(amih);
815 815 amih = NULL;
816 816 }
817 817 }
818 818
819 819 mh_mode = old_mh_mode;
820 820 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
821 821 }
822 822 MemCheck_on(); /* release MALLOC2 lock */
823 823 }
824 824
825 825 #ifndef OPENSSL_NO_FP_API
826 826 void CRYPTO_mem_leaks_fp(FILE *fp)
827 827 {
828 828 BIO *b;
829 829
830 830 if (mh == NULL) return;
831 831 /* Need to turn off memory checking when allocated BIOs ... especially
832 832 * as we're creating them at a time when we're trying to check we've not
833 833 * left anything un-free()'d!! */
834 834 MemCheck_off();
835 835 b = BIO_new(BIO_s_file());
836 836 MemCheck_on();
837 837 if(!b) return;
838 838 BIO_set_fp(b,fp,BIO_NOCLOSE);
839 839 CRYPTO_mem_leaks(b);
840 840 BIO_free(b);
841 841 }
842 842 #endif
843 843
844 844
845 845
846 846 /* FIXME: We really don't allow much to the callback. For example, it has
847 847 no chance of reaching the info stack for the item it processes. Should
848 848 it really be this way? -- Richard Levitte */
849 849 /* NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside crypto.h
850 850 * If this code is restructured, remove the callback type if it is no longer
851 851 * needed. -- Geoff Thorpe */
852 852
853 853 /* Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it
854 854 * is a function pointer and conversion to void * is prohibited. Instead
855 855 * pass its address
856 856 */
857 857
858 858 typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
859 859
860 860 static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
861 861 {
862 862 (*cb)(m->order,m->file,m->line,m->num,m->addr);
863 863 }
864 864
865 865 static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
866 866
867 867 void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
868 868 {
869 869 if (mh == NULL) return;
870 870 CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
871 871 lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
872 872 &cb);
873 873 CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
874 874 }
↓ open down ↓ |
749 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX