mem_dbg.c 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629
  1. /*
  2. * Copyright 1995-2016 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the OpenSSL license (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #include <stdio.h>
  10. #include <stdlib.h>
  11. #include <time.h>
  12. #include "internal/cryptlib.h"
  13. #include "internal/thread_once.h"
  14. #include <openssl/crypto.h>
  15. #include <openssl/buffer.h>
  16. #include "internal/bio.h"
  17. #include <openssl/lhash.h>
  18. #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  19. # include <execinfo.h>
  20. #endif
  21. /*
  22. * The state changes to CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE when
  23. * the application asks for it (usually after library initialisation for
  24. * which no book-keeping is desired). State CRYPTO_MEM_CHECK_ON exists only
  25. * temporarily when the library thinks that certain allocations should not be
  26. * checked (e.g. the data structures used for memory checking). It is not
  27. * suitable as an initial state: the library will unexpectedly enable memory
  28. * checking when it executes one of those sections that want to disable
  29. * checking temporarily. State CRYPTO_MEM_CHECK_ENABLE without ..._ON makes
  30. * no sense whatsoever.
  31. */
  32. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  33. static int mh_mode = CRYPTO_MEM_CHECK_OFF;
  34. #endif
  35. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  36. static unsigned long order = 0; /* number of memory requests */
  37. /*-
  38. * For application-defined information (static C-string `info')
  39. * to be displayed in memory leak list.
  40. * Each thread has its own stack. For applications, there is
  41. * OPENSSL_mem_debug_push("...") to push an entry,
  42. * OPENSSL_mem_debug_pop() to pop an entry,
  43. */
  44. struct app_mem_info_st {
  45. CRYPTO_THREAD_ID threadid;
  46. const char *file;
  47. int line;
  48. const char *info;
  49. struct app_mem_info_st *next; /* tail of thread's stack */
  50. int references;
  51. };
  52. static CRYPTO_ONCE memdbg_init = CRYPTO_ONCE_STATIC_INIT;
  53. static CRYPTO_RWLOCK *malloc_lock = NULL;
  54. static CRYPTO_RWLOCK *long_malloc_lock = NULL;
  55. static CRYPTO_THREAD_LOCAL appinfokey;
  56. /* memory-block description */
  57. struct mem_st {
  58. void *addr;
  59. int num;
  60. const char *file;
  61. int line;
  62. CRYPTO_THREAD_ID threadid;
  63. unsigned long order;
  64. time_t time;
  65. APP_INFO *app_info;
  66. #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  67. void *array[30];
  68. size_t array_siz;
  69. #endif
  70. };
  71. static LHASH_OF(MEM) *mh = NULL; /* hash-table of memory requests (address as
  72. * key); access requires MALLOC2 lock */
  73. /* num_disable > 0 iff mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */
  74. static unsigned int num_disable = 0;
  75. /*
  76. * Valid iff num_disable > 0. long_malloc_lock is locked exactly in this
  77. * case (by the thread named in disabling_thread).
  78. */
  79. static CRYPTO_THREAD_ID disabling_threadid;
  80. DEFINE_RUN_ONCE_STATIC(do_memdbg_init)
  81. {
  82. malloc_lock = CRYPTO_THREAD_lock_new();
  83. long_malloc_lock = CRYPTO_THREAD_lock_new();
  84. if (malloc_lock == NULL || long_malloc_lock == NULL
  85. || !CRYPTO_THREAD_init_local(&appinfokey, NULL)) {
  86. CRYPTO_THREAD_lock_free(malloc_lock);
  87. malloc_lock = NULL;
  88. CRYPTO_THREAD_lock_free(long_malloc_lock);
  89. long_malloc_lock = NULL;
  90. return 0;
  91. }
  92. return 1;
  93. }
  94. static void app_info_free(APP_INFO *inf)
  95. {
  96. if (!inf)
  97. return;
  98. if (--(inf->references) <= 0) {
  99. app_info_free(inf->next);
  100. OPENSSL_free(inf);
  101. }
  102. }
  103. #endif
  104. int CRYPTO_mem_ctrl(int mode)
  105. {
  106. #ifdef OPENSSL_NO_CRYPTO_MDEBUG
  107. return mode - mode;
  108. #else
  109. int ret = mh_mode;
  110. if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
  111. return -1;
  112. CRYPTO_THREAD_write_lock(malloc_lock);
  113. switch (mode) {
  114. default:
  115. break;
  116. case CRYPTO_MEM_CHECK_ON:
  117. mh_mode = CRYPTO_MEM_CHECK_ON | CRYPTO_MEM_CHECK_ENABLE;
  118. num_disable = 0;
  119. break;
  120. case CRYPTO_MEM_CHECK_OFF:
  121. mh_mode = 0;
  122. num_disable = 0;
  123. break;
  124. /* switch off temporarily (for library-internal use): */
  125. case CRYPTO_MEM_CHECK_DISABLE:
  126. if (mh_mode & CRYPTO_MEM_CHECK_ON) {
  127. CRYPTO_THREAD_ID cur = CRYPTO_THREAD_get_current_id();
  128. /* see if we don't have long_malloc_lock already */
  129. if (!num_disable
  130. || !CRYPTO_THREAD_compare_id(disabling_threadid, cur)) {
  131. /*
  132. * Long-time lock long_malloc_lock must not be claimed
  133. * while we're holding malloc_lock, or we'll deadlock
  134. * if somebody else holds long_malloc_lock (and cannot
  135. * release it because we block entry to this function). Give
  136. * them a chance, first, and then claim the locks in
  137. * appropriate order (long-time lock first).
  138. */
  139. CRYPTO_THREAD_unlock(malloc_lock);
  140. /*
  141. * Note that after we have waited for long_malloc_lock and
  142. * malloc_lock, we'll still be in the right "case" and
  143. * "if" branch because MemCheck_start and MemCheck_stop may
  144. * never be used while there are multiple OpenSSL threads.
  145. */
  146. CRYPTO_THREAD_write_lock(long_malloc_lock);
  147. CRYPTO_THREAD_write_lock(malloc_lock);
  148. mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
  149. disabling_threadid = cur;
  150. }
  151. num_disable++;
  152. }
  153. break;
  154. case CRYPTO_MEM_CHECK_ENABLE:
  155. if (mh_mode & CRYPTO_MEM_CHECK_ON) {
  156. if (num_disable) { /* always true, or something is going wrong */
  157. num_disable--;
  158. if (num_disable == 0) {
  159. mh_mode |= CRYPTO_MEM_CHECK_ENABLE;
  160. CRYPTO_THREAD_unlock(long_malloc_lock);
  161. }
  162. }
  163. }
  164. break;
  165. }
  166. CRYPTO_THREAD_unlock(malloc_lock);
  167. return (ret);
  168. #endif
  169. }
  170. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  171. static int mem_check_on(void)
  172. {
  173. int ret = 0;
  174. CRYPTO_THREAD_ID cur;
  175. if (mh_mode & CRYPTO_MEM_CHECK_ON) {
  176. if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
  177. return 0;
  178. cur = CRYPTO_THREAD_get_current_id();
  179. CRYPTO_THREAD_read_lock(malloc_lock);
  180. ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
  181. || !CRYPTO_THREAD_compare_id(disabling_threadid, cur);
  182. CRYPTO_THREAD_unlock(malloc_lock);
  183. }
  184. return (ret);
  185. }
  186. static int mem_cmp(const MEM *a, const MEM *b)
  187. {
  188. #ifdef _WIN64
  189. const char *ap = (const char *)a->addr, *bp = (const char *)b->addr;
  190. if (ap == bp)
  191. return 0;
  192. else if (ap > bp)
  193. return 1;
  194. else
  195. return -1;
  196. #else
  197. return (const char *)a->addr - (const char *)b->addr;
  198. #endif
  199. }
  200. static unsigned long mem_hash(const MEM *a)
  201. {
  202. size_t ret;
  203. ret = (size_t)a->addr;
  204. ret = ret * 17851 + (ret >> 14) * 7 + (ret >> 4) * 251;
  205. return (ret);
  206. }
  207. /* returns 1 if there was an info to pop, 0 if the stack was empty. */
  208. static int pop_info(void)
  209. {
  210. APP_INFO *current = NULL;
  211. if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
  212. return 0;
  213. current = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
  214. if (current != NULL) {
  215. APP_INFO *next = current->next;
  216. if (next != NULL) {
  217. next->references++;
  218. CRYPTO_THREAD_set_local(&appinfokey, next);
  219. } else {
  220. CRYPTO_THREAD_set_local(&appinfokey, NULL);
  221. }
  222. if (--(current->references) <= 0) {
  223. current->next = NULL;
  224. if (next != NULL)
  225. next->references--;
  226. OPENSSL_free(current);
  227. }
  228. return 1;
  229. }
  230. return 0;
  231. }
  232. int CRYPTO_mem_debug_push(const char *info, const char *file, int line)
  233. {
  234. APP_INFO *ami, *amim;
  235. int ret = 0;
  236. if (mem_check_on()) {
  237. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  238. if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
  239. || (ami = OPENSSL_malloc(sizeof(*ami))) == NULL)
  240. goto err;
  241. ami->threadid = CRYPTO_THREAD_get_current_id();
  242. ami->file = file;
  243. ami->line = line;
  244. ami->info = info;
  245. ami->references = 1;
  246. ami->next = NULL;
  247. amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
  248. CRYPTO_THREAD_set_local(&appinfokey, ami);
  249. if (amim != NULL)
  250. ami->next = amim;
  251. ret = 1;
  252. err:
  253. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  254. }
  255. return (ret);
  256. }
  257. int CRYPTO_mem_debug_pop(void)
  258. {
  259. int ret = 0;
  260. if (mem_check_on()) {
  261. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  262. ret = pop_info();
  263. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  264. }
  265. return (ret);
  266. }
  267. static unsigned long break_order_num = 0;
  268. void CRYPTO_mem_debug_malloc(void *addr, size_t num, int before_p,
  269. const char *file, int line)
  270. {
  271. MEM *m, *mm;
  272. APP_INFO *amim;
  273. switch (before_p & 127) {
  274. case 0:
  275. break;
  276. case 1:
  277. if (addr == NULL)
  278. break;
  279. if (mem_check_on()) {
  280. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  281. if (!RUN_ONCE(&memdbg_init, do_memdbg_init)
  282. || (m = OPENSSL_malloc(sizeof(*m))) == NULL) {
  283. OPENSSL_free(addr);
  284. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  285. return;
  286. }
  287. if (mh == NULL) {
  288. if ((mh = lh_MEM_new(mem_hash, mem_cmp)) == NULL) {
  289. OPENSSL_free(addr);
  290. OPENSSL_free(m);
  291. addr = NULL;
  292. goto err;
  293. }
  294. }
  295. m->addr = addr;
  296. m->file = file;
  297. m->line = line;
  298. m->num = num;
  299. m->threadid = CRYPTO_THREAD_get_current_id();
  300. if (order == break_order_num) {
  301. /* BREAK HERE */
  302. m->order = order;
  303. }
  304. m->order = order++;
  305. # ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  306. m->array_siz = backtrace(m->array, OSSL_NELEM(m->array));
  307. # endif
  308. m->time = time(NULL);
  309. amim = (APP_INFO *)CRYPTO_THREAD_get_local(&appinfokey);
  310. m->app_info = amim;
  311. if (amim != NULL)
  312. amim->references++;
  313. if ((mm = lh_MEM_insert(mh, m)) != NULL) {
  314. /* Not good, but don't sweat it */
  315. if (mm->app_info != NULL) {
  316. mm->app_info->references--;
  317. }
  318. OPENSSL_free(mm);
  319. }
  320. err:
  321. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  322. }
  323. break;
  324. }
  325. return;
  326. }
  327. void CRYPTO_mem_debug_free(void *addr, int before_p,
  328. const char *file, int line)
  329. {
  330. MEM m, *mp;
  331. switch (before_p) {
  332. case 0:
  333. if (addr == NULL)
  334. break;
  335. if (mem_check_on() && (mh != NULL)) {
  336. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  337. m.addr = addr;
  338. mp = lh_MEM_delete(mh, &m);
  339. if (mp != NULL) {
  340. app_info_free(mp->app_info);
  341. OPENSSL_free(mp);
  342. }
  343. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  344. }
  345. break;
  346. case 1:
  347. break;
  348. }
  349. }
  350. void CRYPTO_mem_debug_realloc(void *addr1, void *addr2, size_t num,
  351. int before_p, const char *file, int line)
  352. {
  353. MEM m, *mp;
  354. switch (before_p) {
  355. case 0:
  356. break;
  357. case 1:
  358. if (addr2 == NULL)
  359. break;
  360. if (addr1 == NULL) {
  361. CRYPTO_mem_debug_malloc(addr2, num, 128 | before_p, file, line);
  362. break;
  363. }
  364. if (mem_check_on()) {
  365. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  366. m.addr = addr1;
  367. mp = lh_MEM_delete(mh, &m);
  368. if (mp != NULL) {
  369. mp->addr = addr2;
  370. mp->num = num;
  371. #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  372. mp->array_siz = backtrace(mp->array, OSSL_NELEM(mp->array));
  373. #endif
  374. (void)lh_MEM_insert(mh, mp);
  375. }
  376. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  377. }
  378. break;
  379. }
  380. return;
  381. }
  382. typedef struct mem_leak_st {
  383. BIO *bio;
  384. int chunks;
  385. long bytes;
  386. } MEM_LEAK;
  387. static void print_leak(const MEM *m, MEM_LEAK *l)
  388. {
  389. char buf[1024];
  390. char *bufp = buf;
  391. APP_INFO *amip;
  392. int ami_cnt;
  393. struct tm *lcl = NULL;
  394. /*
  395. * Convert between CRYPTO_THREAD_ID (which could be anything at all) and
  396. * a long. This may not be meaningful depending on what CRYPTO_THREAD_ID is
  397. * but hopefully should give something sensible on most platforms
  398. */
  399. union {
  400. CRYPTO_THREAD_ID tid;
  401. unsigned long ltid;
  402. } tid;
  403. CRYPTO_THREAD_ID ti;
  404. #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
  405. lcl = localtime(&m->time);
  406. BIO_snprintf(bufp, BUF_REMAIN, "[%02d:%02d:%02d] ",
  407. lcl->tm_hour, lcl->tm_min, lcl->tm_sec);
  408. bufp += strlen(bufp);
  409. BIO_snprintf(bufp, BUF_REMAIN, "%5lu file=%s, line=%d, ",
  410. m->order, m->file, m->line);
  411. bufp += strlen(bufp);
  412. tid.ltid = 0;
  413. tid.tid = m->threadid;
  414. BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", tid.ltid);
  415. bufp += strlen(bufp);
  416. BIO_snprintf(bufp, BUF_REMAIN, "number=%d, address=%p\n",
  417. m->num, m->addr);
  418. bufp += strlen(bufp);
  419. BIO_puts(l->bio, buf);
  420. l->chunks++;
  421. l->bytes += m->num;
  422. amip = m->app_info;
  423. ami_cnt = 0;
  424. if (amip) {
  425. ti = amip->threadid;
  426. do {
  427. int buf_len;
  428. int info_len;
  429. ami_cnt++;
  430. memset(buf, '>', ami_cnt);
  431. tid.ltid = 0;
  432. tid.tid = amip->threadid;
  433. BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
  434. " thread=%lu, file=%s, line=%d, info=\"",
  435. tid.ltid, amip->file,
  436. amip->line);
  437. buf_len = strlen(buf);
  438. info_len = strlen(amip->info);
  439. if (128 - buf_len - 3 < info_len) {
  440. memcpy(buf + buf_len, amip->info, 128 - buf_len - 3);
  441. buf_len = 128 - 3;
  442. } else {
  443. OPENSSL_strlcpy(buf + buf_len, amip->info, sizeof buf - buf_len);
  444. buf_len = strlen(buf);
  445. }
  446. BIO_snprintf(buf + buf_len, sizeof buf - buf_len, "\"\n");
  447. BIO_puts(l->bio, buf);
  448. amip = amip->next;
  449. }
  450. while (amip && CRYPTO_THREAD_compare_id(amip->threadid, ti));
  451. }
  452. #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  453. {
  454. size_t i;
  455. char **strings = backtrace_symbols(m->array, m->array_siz);
  456. for (i = 0; i < m->array_siz; i++)
  457. fprintf(stderr, "##> %s\n", strings[i]);
  458. free(strings);
  459. }
  460. #endif
  461. }
  462. IMPLEMENT_LHASH_DOALL_ARG_CONST(MEM, MEM_LEAK);
  463. int CRYPTO_mem_leaks(BIO *b)
  464. {
  465. MEM_LEAK ml;
  466. /*
  467. * OPENSSL_cleanup() will free the ex_data locks so we can't have any
  468. * ex_data hanging around
  469. */
  470. bio_free_ex_data(b);
  471. /* Ensure all resources are released */
  472. OPENSSL_cleanup();
  473. if (!RUN_ONCE(&memdbg_init, do_memdbg_init))
  474. return -1;
  475. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  476. ml.bio = b;
  477. ml.bytes = 0;
  478. ml.chunks = 0;
  479. if (mh != NULL)
  480. lh_MEM_doall_MEM_LEAK(mh, print_leak, &ml);
  481. if (ml.chunks != 0) {
  482. BIO_printf(b, "%ld bytes leaked in %d chunks\n", ml.bytes, ml.chunks);
  483. } else {
  484. /*
  485. * Make sure that, if we found no leaks, memory-leak debugging itself
  486. * does not introduce memory leaks (which might irritate external
  487. * debugging tools). (When someone enables leak checking, but does not
  488. * call this function, we declare it to be their fault.)
  489. */
  490. int old_mh_mode;
  491. CRYPTO_THREAD_write_lock(malloc_lock);
  492. /*
  493. * avoid deadlock when lh_free() uses CRYPTO_mem_debug_free(), which uses
  494. * mem_check_on
  495. */
  496. old_mh_mode = mh_mode;
  497. mh_mode = CRYPTO_MEM_CHECK_OFF;
  498. lh_MEM_free(mh);
  499. mh = NULL;
  500. mh_mode = old_mh_mode;
  501. CRYPTO_THREAD_unlock(malloc_lock);
  502. }
  503. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_OFF);
  504. /* Clean up locks etc */
  505. CRYPTO_THREAD_cleanup_local(&appinfokey);
  506. CRYPTO_THREAD_lock_free(malloc_lock);
  507. CRYPTO_THREAD_lock_free(long_malloc_lock);
  508. malloc_lock = NULL;
  509. long_malloc_lock = NULL;
  510. return ml.chunks == 0 ? 1 : 0;
  511. }
  512. # ifndef OPENSSL_NO_STDIO
  513. int CRYPTO_mem_leaks_fp(FILE *fp)
  514. {
  515. BIO *b;
  516. int ret;
  517. /*
  518. * Need to turn off memory checking when allocated BIOs ... especially as
  519. * we're creating them at a time when we're trying to check we've not
  520. * left anything un-free()'d!!
  521. */
  522. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_DISABLE);
  523. b = BIO_new(BIO_s_file());
  524. CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ENABLE);
  525. if (b == NULL)
  526. return -1;
  527. BIO_set_fp(b, fp, BIO_NOCLOSE);
  528. ret = CRYPTO_mem_leaks(b);
  529. BIO_free(b);
  530. return ret;
  531. }
  532. # endif
  533. #endif