mem_dbg.c 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  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. /*
  121. * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
  122. * the application asks for it (usually after library initialisation for
  123. * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
  124. * temporarily when the library thinks that certain allocations should not be
  125. * checked (e.g. the data structures used for memory checking). It is not
  126. * suitable as an initial state: the library will unexpectedly enable memory
  127. * checking when it executes one of those sections that want to disable
  128. * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
  129. * no sense whatsoever.
  130. */
  131. static unsigned long order = 0; /* number of memory requests */
  132. DECLARE_LHASH_OF(MEM);
  133. static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as
  134. * key); access requires MALLOC2 lock */
  135. typedef struct app_mem_info_st
  136. /*-
  137. * For application-defined information (static C-string `info')
  138. * to be displayed in memory leak list.
  139. * Each thread has its own stack. For applications, there is
  140. * CRYPTO_push_info("...") to push an entry,
  141. * CRYPTO_pop_info() to pop an entry,
  142. * CRYPTO_remove_all_info() to pop all entries.
  143. */
  144. {
  145. CRYPTO_THREADID threadid;
  146. const char *file;
  147. int line;
  148. const char *info;
  149. struct app_mem_info_st *next; /* tail of thread's stack */
  150. int references;
  151. } APP_INFO;
  152. static void app_info_free(APP_INFO *);
  153. DECLARE_LHASH_OF(APP_INFO);
  154. static LHASH_OF(APP_INFO) *amih = NULL; /* hash-table with those
  155. * app_mem_info_st's that are at the
  156. * top of their thread's stack (with
  157. * `thread' as key); access requires
  158. * MALLOC2 lock */
  159. typedef struct mem_st
  160. /* memory-block description */
  161. {
  162. void *addr;
  163. int num;
  164. const char *file;
  165. int line;
  166. CRYPTO_THREADID threadid;
  167. unsigned long order;
  168. time_t time;
  169. APP_INFO *app_info;
  170. } MEM;
  171. static long options = /* extra information to be recorded */
  172. #if defined(CRYPTO_MDEBUG_TIME) || defined(CRYPTO_MDEBUG_ALL)
  173. V_CRYPTO_MDEBUG_TIME |
  174. #endif
  175. #if defined(CRYPTO_MDEBUG_THREAD) || defined(CRYPTO_MDEBUG_ALL)
  176. V_CRYPTO_MDEBUG_THREAD |
  177. #endif
  178. 0;
  179. static unsigned int num_disable = 0; /* num_disable > 0 iff mh_mode ==
  180. * CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
  181. /*
  182. * Valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in this
  183. * case (by the thread named in disabling_thread).
  184. */
  185. static CRYPTO_THREADID disabling_threadid;
  186. static void app_info_free(APP_INFO *inf)
  187. {
  188. if (--(inf->references) <= 0) {
  189. if (inf->next != NULL) {
  190. app_info_free(inf->next);
  191. }
  192. OPENSSL_free(inf);
  193. }
  194. }
  195. int CRYPTO_mem_ctrl(int mode)
  196. {
  197. int ret = mh_mode;
  198. CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
  199. switch (mode) {
  200. /*
  201. * for applications (not to be called while multiple threads use the
  202. * library):
  203. */
  204. case CRYPTO_MEM_CHECK_ON: /* aka MemCheck_start() */
  205. mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
  206. num_disable = 0;
  207. break;
  208. case CRYPTO_MEM_CHECK_OFF: /* aka MemCheck_stop() */
  209. mh_mode = 0;
  210. num_disable = 0; /* should be true *before* MemCheck_stop is
  211. * used, or there'll be a lot of confusion */
  212. break;
  213. /* switch off temporarily (for library-internal use): */
  214. case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
  215. if (mh_mode & CRYPTO_MEM_CHECK_ON) {
  216. CRYPTO_THREADID cur;
  217. CRYPTO_THREADID_current(&cur);
  218. /* see if we don't have the MALLOC2 lock already */
  219. if (!num_disable
  220. || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) {
  221. /*
  222. * Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed
  223. * while we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock
  224. * if somebody else holds CRYPTO_LOCK_MALLOC2 (and cannot
  225. * release it because we block entry to this function). Give
  226. * them a chance, first, and then claim the locks in
  227. * appropriate order (long-time lock first).
  228. */
  229. CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
  230. /*
  231. * Note that after we have waited for CRYPTO_LOCK_MALLOC2 and
  232. * CRYPTO_LOCK_MALLOC, we'll still be in the right "case" and
  233. * "if" branch because MemCheck_start and MemCheck_stop may
  234. * never be used while there are multiple OpenSSL threads.
  235. */
  236. CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
  237. CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
  238. mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
  239. CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
  240. }
  241. num_disable++;
  242. }
  243. break;
  244. case CRYPTO_MEM_CHECK_ENABLE: /* aka MemCheck_on() */
  245. if (mh_mode & CRYPTO_MEM_CHECK_ON) {
  246. if (num_disable) { /* always true, or something is going wrong */
  247. num_disable--;
  248. if (num_disable == 0) {
  249. mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
  250. CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
  251. }
  252. }
  253. }
  254. break;
  255. default:
  256. break;
  257. }
  258. CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
  259. return (ret);
  260. }
  261. int CRYPTO_is_mem_check_on(void)
  262. {
  263. int ret = 0;
  264. if (mh_mode & CRYPTO_MEM_CHECK_ON) {
  265. CRYPTO_THREADID cur;
  266. CRYPTO_THREADID_current(&cur);
  267. CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
  268. ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
  269. || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
  270. CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
  271. }
  272. return (ret);
  273. }
  274. void CRYPTO_dbg_set_options(long bits)
  275. {
  276. options = bits;
  277. }
  278. long CRYPTO_dbg_get_options(void)
  279. {
  280. return options;
  281. }
  282. static int mem_cmp(const MEM *a, const MEM *b)
  283. {
  284. #ifdef _WIN64
  285. const char *ap = (const char *)a->addr, *bp = (const char *)b->addr;
  286. if (ap == bp)
  287. return 0;
  288. else if (ap > bp)
  289. return 1;
  290. else
  291. return -1;
  292. #else
  293. return (const char *)a->addr - (const char *)b->addr;
  294. #endif
  295. }
  296. static IMPLEMENT_LHASH_COMP_FN(mem, MEM)
  297. static unsigned long mem_hash(const MEM *a)
  298. {
  299. unsigned long ret;
  300. ret = (unsigned long)a->addr;
  301. ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
  302. return (ret);
  303. }
  304. static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
  305. /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
  306. static int app_info_cmp(const void *a_void, const void *b_void)
  307. {
  308. return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
  309. &((const APP_INFO *)b_void)->threadid);
  310. }
  311. static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
  312. static unsigned long app_info_hash(const APP_INFO *a)
  313. {
  314. unsigned long ret;
  315. ret = CRYPTO_THREADID_hash(&a->threadid);
  316. /* This is left in as a "who am I to question legacy?" measure */
  317. ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
  318. return (ret);
  319. }
  320. static IMPLEMENT_LHASH_HASH_FN(app_info, APP_INFO)
  321. static APP_INFO *pop_info(void)
  322. {
  323. APP_INFO tmp;
  324. APP_INFO *ret = NULL;
  325. if (amih != NULL) {
  326. CRYPTO_THREADID_current(&tmp.threadid);
  327. if ((ret = lh_APP_INFO_delete(amih, &tmp)) != NULL) {
  328. APP_INFO *next = ret->next;
  329. if (next != NULL) {
  330. next->references++;
  331. (void)lh_APP_INFO_insert(amih, next);
  332. }
  333. #ifdef LEVITTE_DEBUG_MEM
  334. if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid)) {
  335. fprintf(stderr,
  336. "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
  337. CRYPTO_THREADID_hash(&ret->threadid),
  338. CRYPTO_THREADID_hash(&tmp.threadid));
  339. abort();
  340. }
  341. #endif
  342. if (--(ret->references) <= 0) {
  343. ret->next = NULL;
  344. if (next != NULL)
  345. next->references--;
  346. OPENSSL_free(ret);
  347. }
  348. }
  349. }
  350. return (ret);
  351. }
  352. int CRYPTO_push_info_(const char *info, const char *file, int line)
  353. {
  354. APP_INFO *ami, *amim;
  355. int ret = 0;
  356. if (is_MemCheck_on()) {
  357. MemCheck_off(); /* obtain MALLOC2 lock */
  358. if ((ami = (APP_INFO *)OPENSSL_malloc(sizeof(APP_INFO))) == NULL) {
  359. ret = 0;
  360. goto err;
  361. }
  362. if (amih == NULL) {
  363. if ((amih = lh_APP_INFO_new()) == NULL) {
  364. OPENSSL_free(ami);
  365. ret = 0;
  366. goto err;
  367. }
  368. }
  369. CRYPTO_THREADID_current(&ami->threadid);
  370. ami->file = file;
  371. ami->line = line;
  372. ami->info = info;
  373. ami->references = 1;
  374. ami->next = NULL;
  375. if ((amim = lh_APP_INFO_insert(amih, ami)) != NULL) {
  376. #ifdef LEVITTE_DEBUG_MEM
  377. if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid)) {
  378. fprintf(stderr,
  379. "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
  380. CRYPTO_THREADID_hash(&amim->threadid),
  381. CRYPTO_THREADID_hash(&ami->threadid));
  382. abort();
  383. }
  384. #endif
  385. ami->next = amim;
  386. }
  387. err:
  388. MemCheck_on(); /* release MALLOC2 lock */
  389. }
  390. return (ret);
  391. }
  392. int CRYPTO_pop_info(void)
  393. {
  394. int ret = 0;
  395. if (is_MemCheck_on()) { /* _must_ be true, or something went severely
  396. * wrong */
  397. MemCheck_off(); /* obtain MALLOC2 lock */
  398. ret = (pop_info() != NULL);
  399. MemCheck_on(); /* release MALLOC2 lock */
  400. }
  401. return (ret);
  402. }
  403. int CRYPTO_remove_all_info(void)
  404. {
  405. int ret = 0;
  406. if (is_MemCheck_on()) { /* _must_ be true */
  407. MemCheck_off(); /* obtain MALLOC2 lock */
  408. while (pop_info() != NULL)
  409. ret++;
  410. MemCheck_on(); /* release MALLOC2 lock */
  411. }
  412. return (ret);
  413. }
  414. static unsigned long break_order_num = 0;
  415. void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
  416. int before_p)
  417. {
  418. MEM *m, *mm;
  419. APP_INFO tmp, *amim;
  420. switch (before_p & 127) {
  421. case 0:
  422. break;
  423. case 1:
  424. if (addr == NULL)
  425. break;
  426. if (is_MemCheck_on()) {
  427. MemCheck_off(); /* make sure we hold MALLOC2 lock */
  428. if ((m = (MEM *)OPENSSL_malloc(sizeof(MEM))) == NULL) {
  429. OPENSSL_free(addr);
  430. MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
  431. * to 0 */
  432. return;
  433. }
  434. if (mh == NULL) {
  435. if ((mh = lh_MEM_new()) == NULL) {
  436. OPENSSL_free(addr);
  437. OPENSSL_free(m);
  438. addr = NULL;
  439. goto err;
  440. }
  441. }
  442. m->addr = addr;
  443. m->file = file;
  444. m->line = line;
  445. m->num = num;
  446. if (options & V_CRYPTO_MDEBUG_THREAD)
  447. CRYPTO_THREADID_current(&m->threadid);
  448. else
  449. memset(&m->threadid, 0, sizeof(m->threadid));
  450. if (order == break_order_num) {
  451. /* BREAK HERE */
  452. m->order = order;
  453. }
  454. m->order = order++;
  455. #ifdef LEVITTE_DEBUG_MEM
  456. fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n",
  457. m->order, (before_p & 128) ? '*' : '+', m->addr, m->num);
  458. #endif
  459. if (options & V_CRYPTO_MDEBUG_TIME)
  460. m->time = time(NULL);
  461. else
  462. m->time = 0;
  463. CRYPTO_THREADID_current(&tmp.threadid);
  464. m->app_info = NULL;
  465. if (amih != NULL
  466. && (amim = lh_APP_INFO_retrieve(amih, &tmp)) != NULL) {
  467. m->app_info = amim;
  468. amim->references++;
  469. }
  470. if ((mm = lh_MEM_insert(mh, m)) != NULL) {
  471. /* Not good, but don't sweat it */
  472. if (mm->app_info != NULL) {
  473. mm->app_info->references--;
  474. }
  475. OPENSSL_free(mm);
  476. }
  477. err:
  478. MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
  479. * to 0 */
  480. }
  481. break;
  482. }
  483. return;
  484. }
  485. void CRYPTO_dbg_free(void *addr, int before_p)
  486. {
  487. MEM m, *mp;
  488. switch (before_p) {
  489. case 0:
  490. if (addr == NULL)
  491. break;
  492. if (is_MemCheck_on() && (mh != NULL)) {
  493. MemCheck_off(); /* make sure we hold MALLOC2 lock */
  494. m.addr = addr;
  495. mp = lh_MEM_delete(mh, &m);
  496. if (mp != NULL) {
  497. #ifdef LEVITTE_DEBUG_MEM
  498. fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n",
  499. mp->order, mp->addr, mp->num);
  500. #endif
  501. if (mp->app_info != NULL)
  502. app_info_free(mp->app_info);
  503. OPENSSL_free(mp);
  504. }
  505. MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
  506. * to 0 */
  507. }
  508. break;
  509. case 1:
  510. break;
  511. }
  512. }
  513. void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
  514. const char *file, int line, int before_p)
  515. {
  516. MEM m, *mp;
  517. #ifdef LEVITTE_DEBUG_MEM
  518. fprintf(stderr,
  519. "LEVITTE_DEBUG_MEM: --> CRYPTO_dbg_malloc(addr1 = %p, addr2 = %p, num = %d, file = \"%s\", line = %d, before_p = %d)\n",
  520. addr1, addr2, num, file, line, before_p);
  521. #endif
  522. switch (before_p) {
  523. case 0:
  524. break;
  525. case 1:
  526. if (addr2 == NULL)
  527. break;
  528. if (addr1 == NULL) {
  529. CRYPTO_dbg_malloc(addr2, num, file, line, 128 | before_p);
  530. break;
  531. }
  532. if (is_MemCheck_on()) {
  533. MemCheck_off(); /* make sure we hold MALLOC2 lock */
  534. m.addr = addr1;
  535. mp = lh_MEM_delete(mh, &m);
  536. if (mp != NULL) {
  537. #ifdef LEVITTE_DEBUG_MEM
  538. fprintf(stderr,
  539. "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n",
  540. mp->order, mp->addr, mp->num, addr2, num);
  541. #endif
  542. mp->addr = addr2;
  543. mp->num = num;
  544. (void)lh_MEM_insert(mh, mp);
  545. }
  546. MemCheck_on(); /* release MALLOC2 lock if num_disabled drops
  547. * to 0 */
  548. }
  549. break;
  550. }
  551. return;
  552. }
  553. typedef struct mem_leak_st {
  554. BIO *bio;
  555. int chunks;
  556. long bytes;
  557. } MEM_LEAK;
  558. static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
  559. {
  560. char buf[1024];
  561. char *bufp = buf;
  562. APP_INFO *amip;
  563. int ami_cnt;
  564. struct tm *lcl = NULL;
  565. CRYPTO_THREADID ti;
  566. #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
  567. if (m->addr == (char *)l->bio)
  568. return;
  569. if (options & V_CRYPTO_MDEBUG_TIME) {
  570. lcl = localtime(&m->time);
  571. BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
  572. lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
  573. bufp += strlen(bufp);
  574. }
  575. BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
  576. m->order, m->file, m->line);
  577. bufp += strlen(bufp);
  578. if (options & V_CRYPTO_MDEBUG_THREAD) {
  579. BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
  580. CRYPTO_THREADID_hash(&m->threadid));
  581. bufp += strlen(bufp);
  582. }
  583. BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%08lX\n",
  584. m->num, (unsigned long)m->addr);
  585. bufp += strlen(bufp);
  586. BIO_puts(l->bio, buf);
  587. l->chunks++;
  588. l->bytes += m->num;
  589. amip = m->app_info;
  590. ami_cnt = 0;
  591. if (!amip)
  592. return;
  593. CRYPTO_THREADID_cpy(&ti, &amip->threadid);
  594. do {
  595. int buf_len;
  596. int info_len;
  597. ami_cnt++;
  598. memset(buf, '>', ami_cnt);
  599. BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
  600. " thread=%lu, file=%s, line=%d, info=\"",
  601. CRYPTO_THREADID_hash(&amip->threadid), amip->file,
  602. amip->line);
  603. buf_len = strlen(buf);
  604. info_len = strlen(amip->info);
  605. if (128 - buf_len - 3 < info_len) {
  606. memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
  607. buf_len = 128 - 3;
  608. } else {
  609. BUF_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
  610. buf_len = strlen(buf);
  611. }
  612. BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
  613. BIO_puts(l->bio, buf);
  614. amip = amip->next;
  615. }
  616. while (amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
  617. #ifdef LEVITTE_DEBUG_MEM
  618. if (amip) {
  619. fprintf(stderr, "Thread switch detected in backtrace!!!!\n");
  620. abort();
  621. }
  622. #endif
  623. }
  624. static IMPLEMENT_LHASH_DOALL_ARG_FN(print_leak, const MEM, MEM_LEAK)
  625. void CRYPTO_mem_leaks(BIO *b)
  626. {
  627. MEM_LEAK ml;
  628. if (mh == NULL && amih == NULL)
  629. return;
  630. MemCheck_off(); /* obtain MALLOC2 lock */
  631. ml.bio = b;
  632. ml.bytes = 0;
  633. ml.chunks = 0;
  634. if (mh != NULL)
  635. lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(print_leak), MEM_LEAK, &ml);
  636. if (ml.chunks != 0) {
  637. BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks);
  638. #ifdef CRYPTO_MDEBUG_ABORT
  639. abort();
  640. #endif
  641. } else {
  642. /*
  643. * Make sure that, if we found no leaks, memory-leak debugging itself
  644. * does not introduce memory leaks (which might irritate external
  645. * debugging tools). (When someone enables leak checking, but does not
  646. * call this function, we declare it to be their fault.) XXX This
  647. * should be in CRYPTO_mem_leaks_cb, and CRYPTO_mem_leaks should be
  648. * implemented by using CRYPTO_mem_leaks_cb. (Also there should be a
  649. * variant of lh_doall_arg that takes a function pointer instead of a
  650. * void *; this would obviate the ugly and illegal void_fn_to_char
  651. * kludge in CRYPTO_mem_leaks_cb. Otherwise the code police will come
  652. * and get us.)
  653. */
  654. int old_mh_mode;
  655. CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
  656. /*
  657. * avoid deadlock when lh_free() uses CRYPTO_dbg_free(), which uses
  658. * CRYPTO_is_mem_check_on
  659. */
  660. old_mh_mode = mh_mode;
  661. mh_mode = CRYPTO_MEM_CHECK_OFF;
  662. if (mh != NULL) {
  663. lh_MEM_free(mh);
  664. mh = NULL;
  665. }
  666. if (amih != NULL) {
  667. if (lh_APP_INFO_num_items(amih) == 0) {
  668. lh_APP_INFO_free(amih);
  669. amih = NULL;
  670. }
  671. }
  672. mh_mode = old_mh_mode;
  673. CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC);
  674. }
  675. MemCheck_on(); /* release MALLOC2 lock */
  676. }
  677. #ifndef OPENSSL_NO_FP_API
  678. void CRYPTO_mem_leaks_fp(FILE *fp)
  679. {
  680. BIO *b;
  681. if (mh == NULL)
  682. return;
  683. /*
  684. * Need to turn off memory checking when allocated BIOs ... especially as
  685. * we're creating them at a time when we're trying to check we've not
  686. * left anything un-free()'d!!
  687. */
  688. MemCheck_off();
  689. b = BIO_new(BIO_s_file());
  690. MemCheck_on();
  691. if (!b)
  692. return;
  693. BIO_set_fp(b, fp, BIO_NOCLOSE);
  694. CRYPTO_mem_leaks(b);
  695. BIO_free(b);
  696. }
  697. #endif
  698. /*
  699. * FIXME: We really don't allow much to the callback. For example, it has no
  700. * chance of reaching the info stack for the item it processes. Should it
  701. * really be this way? -- Richard Levitte
  702. */
  703. /*
  704. * NB: The prototypes have been typedef'd to CRYPTO_MEM_LEAK_CB inside
  705. * crypto.h If this code is restructured, remove the callback type if it is
  706. * no longer needed. -- Geoff Thorpe
  707. */
  708. /*
  709. * Can't pass CRYPTO_MEM_LEAK_CB directly to lh_MEM_doall_arg because it is a
  710. * function pointer and conversion to void * is prohibited. Instead pass its
  711. * address
  712. */
  713. typedef CRYPTO_MEM_LEAK_CB *PCRYPTO_MEM_LEAK_CB;
  714. static void cb_leak_doall_arg(const MEM *m, PCRYPTO_MEM_LEAK_CB *cb)
  715. {
  716. (*cb) (m->order, m->file, m->line, m->num, m->addr);
  717. }
  718. static IMPLEMENT_LHASH_DOALL_ARG_FN(cb_leak, const MEM, PCRYPTO_MEM_LEAK_CB)
  719. void CRYPTO_mem_leaks_cb(CRYPTO_MEM_LEAK_CB *cb)
  720. {
  721. if (mh == NULL)
  722. return;
  723. CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
  724. lh_MEM_doall_arg(mh, LHASH_DOALL_ARG_FN(cb_leak), PCRYPTO_MEM_LEAK_CB,
  725. &cb);
  726. CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC2);
  727. }