2
0

mem.c 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323
  1. /*
  2. * Copyright 1995-2018 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 "e_os.h"
  10. #include "internal/cryptlib.h"
  11. #include "crypto/cryptlib.h"
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <limits.h>
  15. #include <openssl/crypto.h>
  16. #ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  17. # include <execinfo.h>
  18. #endif
  19. /*
  20. * the following pointers may be changed as long as 'allow_customize' is set
  21. */
  22. static int allow_customize = 1;
  23. static void *(*malloc_impl)(size_t, const char *, int)
  24. = CRYPTO_malloc;
  25. static void *(*realloc_impl)(void *, size_t, const char *, int)
  26. = CRYPTO_realloc;
  27. static void (*free_impl)(void *, const char *, int)
  28. = CRYPTO_free;
  29. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  30. # include "internal/tsan_assist.h"
  31. static TSAN_QUALIFIER int malloc_count;
  32. static TSAN_QUALIFIER int realloc_count;
  33. static TSAN_QUALIFIER int free_count;
  34. # define INCREMENT(x) tsan_counter(&(x))
  35. static char *md_failstring;
  36. static long md_count;
  37. static int md_fail_percent = 0;
  38. static int md_tracefd = -1;
  39. static int call_malloc_debug = 1;
  40. static void parseit(void);
  41. static int shouldfail(void);
  42. # define FAILTEST() if (shouldfail()) return NULL
  43. #else
  44. static int call_malloc_debug = 0;
  45. # define INCREMENT(x) /* empty */
  46. # define FAILTEST() /* empty */
  47. #endif
  48. int CRYPTO_set_mem_functions(
  49. void *(*m)(size_t, const char *, int),
  50. void *(*r)(void *, size_t, const char *, int),
  51. void (*f)(void *, const char *, int))
  52. {
  53. if (!allow_customize)
  54. return 0;
  55. if (m)
  56. malloc_impl = m;
  57. if (r)
  58. realloc_impl = r;
  59. if (f)
  60. free_impl = f;
  61. return 1;
  62. }
  63. int CRYPTO_set_mem_debug(int flag)
  64. {
  65. if (!allow_customize)
  66. return 0;
  67. call_malloc_debug = flag;
  68. return 1;
  69. }
  70. void CRYPTO_get_mem_functions(
  71. void *(**m)(size_t, const char *, int),
  72. void *(**r)(void *, size_t, const char *, int),
  73. void (**f)(void *, const char *, int))
  74. {
  75. if (m != NULL)
  76. *m = malloc_impl;
  77. if (r != NULL)
  78. *r = realloc_impl;
  79. if (f != NULL)
  80. *f = free_impl;
  81. }
  82. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  83. void CRYPTO_get_alloc_counts(int *mcount, int *rcount, int *fcount)
  84. {
  85. if (mcount != NULL)
  86. *mcount = tsan_load(&malloc_count);
  87. if (rcount != NULL)
  88. *rcount = tsan_load(&realloc_count);
  89. if (fcount != NULL)
  90. *fcount = tsan_load(&free_count);
  91. }
  92. /*
  93. * Parse a "malloc failure spec" string. This likes like a set of fields
  94. * separated by semicolons. Each field has a count and an optional failure
  95. * percentage. For example:
  96. * 100@0;100@25;0@0
  97. * or 100;100@25;0
  98. * This means 100 mallocs succeed, then next 100 fail 25% of the time, and
  99. * all remaining (count is zero) succeed.
  100. */
  101. static void parseit(void)
  102. {
  103. char *semi = strchr(md_failstring, ';');
  104. char *atsign;
  105. if (semi != NULL)
  106. *semi++ = '\0';
  107. /* Get the count (atol will stop at the @ if there), and percentage */
  108. md_count = atol(md_failstring);
  109. atsign = strchr(md_failstring, '@');
  110. md_fail_percent = atsign == NULL ? 0 : atoi(atsign + 1);
  111. if (semi != NULL)
  112. md_failstring = semi;
  113. }
  114. /*
  115. * Windows doesn't have random(), but it has rand()
  116. * Some rand() implementations aren't good, but we're not
  117. * dealing with secure randomness here.
  118. */
  119. # ifdef _WIN32
  120. # define random() rand()
  121. # endif
  122. /*
  123. * See if the current malloc should fail.
  124. */
  125. static int shouldfail(void)
  126. {
  127. int roll = (int)(random() % 100);
  128. int shoulditfail = roll < md_fail_percent;
  129. # ifndef _WIN32
  130. /* suppressed on Windows as POSIX-like file descriptors are non-inheritable */
  131. int len;
  132. char buff[80];
  133. if (md_tracefd > 0) {
  134. BIO_snprintf(buff, sizeof(buff),
  135. "%c C%ld %%%d R%d\n",
  136. shoulditfail ? '-' : '+', md_count, md_fail_percent, roll);
  137. len = strlen(buff);
  138. if (write(md_tracefd, buff, len) != len)
  139. perror("shouldfail write failed");
  140. # ifndef OPENSSL_NO_CRYPTO_MDEBUG_BACKTRACE
  141. if (shoulditfail) {
  142. void *addrs[30];
  143. int num = backtrace(addrs, OSSL_NELEM(addrs));
  144. backtrace_symbols_fd(addrs, num, md_tracefd);
  145. }
  146. # endif
  147. }
  148. # endif
  149. if (md_count) {
  150. /* If we used up this one, go to the next. */
  151. if (--md_count == 0)
  152. parseit();
  153. }
  154. return shoulditfail;
  155. }
  156. void ossl_malloc_setup_failures(void)
  157. {
  158. const char *cp = getenv("OPENSSL_MALLOC_FAILURES");
  159. if (cp != NULL && (md_failstring = strdup(cp)) != NULL)
  160. parseit();
  161. if ((cp = getenv("OPENSSL_MALLOC_FD")) != NULL)
  162. md_tracefd = atoi(cp);
  163. }
  164. #endif
  165. void *CRYPTO_malloc(size_t num, const char *file, int line)
  166. {
  167. void *ret = NULL;
  168. INCREMENT(malloc_count);
  169. if (malloc_impl != NULL && malloc_impl != CRYPTO_malloc)
  170. return malloc_impl(num, file, line);
  171. if (num == 0)
  172. return NULL;
  173. FAILTEST();
  174. if (allow_customize) {
  175. /*
  176. * Disallow customization after the first allocation. We only set this
  177. * if necessary to avoid a store to the same cache line on every
  178. * allocation.
  179. */
  180. allow_customize = 0;
  181. }
  182. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  183. if (call_malloc_debug) {
  184. CRYPTO_mem_debug_malloc(NULL, num, 0, file, line);
  185. ret = malloc(num);
  186. CRYPTO_mem_debug_malloc(ret, num, 1, file, line);
  187. } else {
  188. ret = malloc(num);
  189. }
  190. #else
  191. (void)(file); (void)(line);
  192. ret = malloc(num);
  193. #endif
  194. return ret;
  195. }
  196. void *CRYPTO_zalloc(size_t num, const char *file, int line)
  197. {
  198. void *ret = CRYPTO_malloc(num, file, line);
  199. FAILTEST();
  200. if (ret != NULL)
  201. memset(ret, 0, num);
  202. return ret;
  203. }
  204. void *CRYPTO_realloc(void *str, size_t num, const char *file, int line)
  205. {
  206. INCREMENT(realloc_count);
  207. if (realloc_impl != NULL && realloc_impl != &CRYPTO_realloc)
  208. return realloc_impl(str, num, file, line);
  209. FAILTEST();
  210. if (str == NULL)
  211. return CRYPTO_malloc(num, file, line);
  212. if (num == 0) {
  213. CRYPTO_free(str, file, line);
  214. return NULL;
  215. }
  216. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  217. if (call_malloc_debug) {
  218. void *ret;
  219. CRYPTO_mem_debug_realloc(str, NULL, num, 0, file, line);
  220. ret = realloc(str, num);
  221. CRYPTO_mem_debug_realloc(str, ret, num, 1, file, line);
  222. return ret;
  223. }
  224. #else
  225. (void)(file); (void)(line);
  226. #endif
  227. return realloc(str, num);
  228. }
  229. void *CRYPTO_clear_realloc(void *str, size_t old_len, size_t num,
  230. const char *file, int line)
  231. {
  232. void *ret = NULL;
  233. if (str == NULL)
  234. return CRYPTO_malloc(num, file, line);
  235. if (num == 0) {
  236. CRYPTO_clear_free(str, old_len, file, line);
  237. return NULL;
  238. }
  239. /* Can't shrink the buffer since memcpy below copies |old_len| bytes. */
  240. if (num < old_len) {
  241. OPENSSL_cleanse((char*)str + num, old_len - num);
  242. return str;
  243. }
  244. ret = CRYPTO_malloc(num, file, line);
  245. if (ret != NULL) {
  246. memcpy(ret, str, old_len);
  247. CRYPTO_clear_free(str, old_len, file, line);
  248. }
  249. return ret;
  250. }
  251. void CRYPTO_free(void *str, const char *file, int line)
  252. {
  253. INCREMENT(free_count);
  254. if (free_impl != NULL && free_impl != &CRYPTO_free) {
  255. free_impl(str, file, line);
  256. return;
  257. }
  258. #ifndef OPENSSL_NO_CRYPTO_MDEBUG
  259. if (call_malloc_debug) {
  260. CRYPTO_mem_debug_free(str, 0, file, line);
  261. free(str);
  262. CRYPTO_mem_debug_free(str, 1, file, line);
  263. } else {
  264. free(str);
  265. }
  266. #else
  267. free(str);
  268. #endif
  269. }
  270. void CRYPTO_clear_free(void *str, size_t num, const char *file, int line)
  271. {
  272. if (str == NULL)
  273. return;
  274. if (num)
  275. OPENSSL_cleanse(str, num);
  276. CRYPTO_free(str, file, line);
  277. }