mem_dbg.c 23 KB

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