memory.c 47 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626
  1. /* memory.c
  2. *
  3. * Copyright (C) 2006-2023 wolfSSL Inc.
  4. *
  5. * This file is part of wolfSSL.
  6. *
  7. * wolfSSL is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 2 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * wolfSSL is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program; if not, write to the Free Software
  19. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
  20. */
  21. #ifdef HAVE_CONFIG_H
  22. #include <config.h>
  23. #endif
  24. #ifdef WOLFSSL_LINUXKM
  25. /* inhibit "#undef current" in linuxkm_wc_port.h, included from wc_port.h,
  26. * because needed in linuxkm_memory.c, included below.
  27. */
  28. #define WOLFSSL_NEED_LINUX_CURRENT
  29. #endif
  30. #include <wolfssl/wolfcrypt/types.h>
  31. /*
  32. Possible memory options:
  33. * NO_WOLFSSL_MEMORY: Disables wolf memory callback support. When not defined settings.h defines USE_WOLFSSL_MEMORY.
  34. * WOLFSSL_STATIC_MEMORY: Turns on the use of static memory buffers and functions.
  35. This allows for using static memory instead of dynamic.
  36. * WOLFSSL_STATIC_ALIGN: Define defaults to 16 to indicate static memory alignment.
  37. * HAVE_IO_POOL: Enables use of static thread safe memory pool for input/output buffers.
  38. * XMALLOC_OVERRIDE: Allows override of the XMALLOC, XFREE and XREALLOC macros.
  39. * XMALLOC_USER: Allows custom XMALLOC, XFREE and XREALLOC functions to be defined.
  40. * WOLFSSL_NO_MALLOC: Disables the fall-back case to use STDIO malloc/free when no callbacks are set.
  41. * WOLFSSL_TRACK_MEMORY: Enables memory tracking for total stats and list of allocated memory.
  42. * WOLFSSL_DEBUG_MEMORY: Enables extra function and line number args for memory callbacks.
  43. * WOLFSSL_DEBUG_MEMORY_PRINT: Enables printing of each malloc/free.
  44. * WOLFSSL_MALLOC_CHECK: Reports malloc or alignment failure using WOLFSSL_STATIC_ALIGN
  45. * WOLFSSL_FORCE_MALLOC_FAIL_TEST: Used for internal testing to induce random malloc failures.
  46. * WOLFSSL_HEAP_TEST: Used for internal testing of heap hint
  47. * WOLFSSL_MEM_FAIL_COUNT: Fail memory allocation at a count from
  48. * environment variable: MEM_FAIL_CNT.
  49. */
  50. #ifdef WOLFSSL_ZEPHYR
  51. #undef realloc
  52. void *z_realloc(void *ptr, size_t size)
  53. {
  54. if (ptr == NULL)
  55. ptr = malloc(size);
  56. else
  57. ptr = realloc(ptr, size);
  58. return ptr;
  59. }
  60. #define realloc z_realloc
  61. #endif
  62. #ifdef USE_WOLFSSL_MEMORY
  63. #include <wolfssl/wolfcrypt/memory.h>
  64. #include <wolfssl/wolfcrypt/error-crypt.h>
  65. #include <wolfssl/wolfcrypt/logging.h>
  66. #if defined(WOLFSSL_DEBUG_MEMORY) && defined(WOLFSSL_DEBUG_MEMORY_PRINT)
  67. #include <stdio.h>
  68. #endif
  69. #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
  70. static int gMemFailCountSeed;
  71. static int gMemFailCount;
  72. void wolfSSL_SetMemFailCount(int memFailCount)
  73. {
  74. if (gMemFailCountSeed == 0) {
  75. gMemFailCountSeed = memFailCount;
  76. gMemFailCount = memFailCount;
  77. }
  78. }
  79. #endif
  80. #if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL) || \
  81. defined(WOLFSSL_MEMORY_LOG)
  82. #include <stdio.h>
  83. #endif
  84. /* Set these to default values initially. */
  85. static wolfSSL_Malloc_cb malloc_function = NULL;
  86. static wolfSSL_Free_cb free_function = NULL;
  87. static wolfSSL_Realloc_cb realloc_function = NULL;
  88. int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf,
  89. wolfSSL_Free_cb ff,
  90. wolfSSL_Realloc_cb rf)
  91. {
  92. malloc_function = mf;
  93. free_function = ff;
  94. realloc_function = rf;
  95. return 0;
  96. }
  97. int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf,
  98. wolfSSL_Free_cb* ff,
  99. wolfSSL_Realloc_cb* rf)
  100. {
  101. if (mf) *mf = malloc_function;
  102. if (ff) *ff = free_function;
  103. if (rf) *rf = realloc_function;
  104. return 0;
  105. }
  106. #ifdef WOLFSSL_MEM_FAIL_COUNT
  107. static wolfSSL_Mutex memFailMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(memFailMutex);
  108. int mem_fail_allocs = 0;
  109. int mem_fail_frees = 0;
  110. int mem_fail_cnt = 0;
  111. void wc_MemFailCount_Init()
  112. {
  113. char* cnt;
  114. #ifndef WOLFSSL_MUTEX_INITIALIZER
  115. wc_InitMutex(&memFailMutex);
  116. #endif
  117. cnt = getenv("MEM_FAIL_CNT");
  118. if (cnt != NULL) {
  119. fprintf(stderr, "MemFailCount At: %d\n", mem_fail_cnt);
  120. mem_fail_cnt = atoi(cnt);
  121. }
  122. }
  123. static int wc_MemFailCount_AllocMem(void)
  124. {
  125. int ret = 1;
  126. wc_LockMutex(&memFailMutex);
  127. if ((mem_fail_cnt > 0) && (mem_fail_cnt <= mem_fail_allocs + 1)) {
  128. ret = 0;
  129. }
  130. else {
  131. mem_fail_allocs++;
  132. }
  133. wc_UnLockMutex(&memFailMutex);
  134. return ret;
  135. }
  136. static void wc_MemFailCount_FreeMem(void)
  137. {
  138. wc_LockMutex(&memFailMutex);
  139. mem_fail_frees++;
  140. wc_UnLockMutex(&memFailMutex);
  141. }
  142. void wc_MemFailCount_Free()
  143. {
  144. #ifndef WOLFSSL_MUTEX_INITIALIZER
  145. wc_FreeMutex(&memFailMutex);
  146. #endif
  147. fprintf(stderr, "MemFailCount Total: %d\n", mem_fail_allocs);
  148. fprintf(stderr, "MemFailCount Frees: %d\n", mem_fail_frees);
  149. }
  150. #endif
  151. #ifndef WOLFSSL_STATIC_MEMORY
  152. #ifdef WOLFSSL_CHECK_MEM_ZERO
  153. #ifndef WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN
  154. /* Number of entries in table of addresses to check. */
  155. #define WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN 256
  156. #endif
  157. /* Alignment to maintain when adding length to allocated pointer.
  158. * Intel x64 wants to use aligned loads of XMM registers.
  159. */
  160. #define MEM_ALIGN 16
  161. /* An address that is meant to be all zeros for its length. */
  162. typedef struct MemZero {
  163. /* Name of address to check. */
  164. const char* name;
  165. /* Address to check. */
  166. const void* addr;
  167. /* Length of data that must be zero. */
  168. size_t len;
  169. } MemZero;
  170. /* List of addresses to check. */
  171. static MemZero memZero[WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN];
  172. /* Next index to place address at.
  173. * -1 indicates uninitialized.
  174. * If nextIdx is equal to WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN then all entries
  175. * have been used.
  176. */
  177. static int nextIdx = -1;
  178. /* Mutex to protect modifying list of addresses to check. */
  179. static wolfSSL_Mutex zeroMutex WOLFSSL_MUTEX_INITIALIZER_CLAUSE(zeroMutex);
  180. /* Initialize the table of addresses and the mutex.
  181. */
  182. void wc_MemZero_Init()
  183. {
  184. /* Clear the table to more easily see what is valid. */
  185. XMEMSET(memZero, 0, sizeof(memZero));
  186. /* Initialize mutex. */
  187. #ifndef WOLFSSL_MUTEX_INITIALIZER
  188. wc_InitMutex(&zeroMutex);
  189. #endif
  190. /* Next index is first entry. */
  191. nextIdx = 0;
  192. }
  193. /* Free the mutex and check we have not any uncheck addresses.
  194. */
  195. void wc_MemZero_Free()
  196. {
  197. /* Free mutex. */
  198. #ifndef WOLFSSL_MUTEX_INITIALIZER
  199. wc_FreeMutex(&zeroMutex);
  200. #endif
  201. /* Make sure we checked all addresses. */
  202. if (nextIdx > 0) {
  203. int i;
  204. fprintf(stderr, "[MEM_ZERO] Unseen: %d\n", nextIdx);
  205. for (i = 0; i < nextIdx; i++) {
  206. fprintf(stderr, " %s - %p:%ld\n", memZero[i].name, memZero[i].addr,
  207. memZero[i].len);
  208. }
  209. }
  210. /* Uninitialized value in next index. */
  211. nextIdx = -1;
  212. }
  213. /* Add an address to check.
  214. *
  215. * @param [in] name Name of address to check.
  216. * @param [in] addr Address that needs to be checked.
  217. * @param [in] len Length of data that must be zero.
  218. */
  219. void wc_MemZero_Add(const char* name, const void* addr, size_t len)
  220. {
  221. /* Initialize if not done. */
  222. if (nextIdx == -1) {
  223. wc_MemZero_Init();
  224. }
  225. /* Add an entry to the table while locked. */
  226. wc_LockMutex(&zeroMutex);
  227. if (nextIdx < WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN) {
  228. /* Fill in the next entry and update next index. */
  229. memZero[nextIdx].name = name;
  230. memZero[nextIdx].addr = addr;
  231. memZero[nextIdx].len = len;
  232. nextIdx++;
  233. }
  234. else {
  235. /* Abort when too many entries. */
  236. fprintf(stderr, "\n[MEM_ZERO] Too many addresses to check\n");
  237. fprintf(stderr, "[MEM_ZERO] WOLFSSL_MEM_CHECK_ZERO_CACHE_LEN\n");
  238. abort();
  239. }
  240. wc_UnLockMutex(&zeroMutex);
  241. }
  242. /* Check the memory in the range of the address for memory that must be zero.
  243. *
  244. * @param [in] addr Start address of memory that is to be checked.
  245. * @param [in] len Length of data associated with address.
  246. */
  247. void wc_MemZero_Check(void* addr, size_t len)
  248. {
  249. int i;
  250. size_t j;
  251. wc_LockMutex(&zeroMutex);
  252. /* Look at each address for overlap with address passes in. */
  253. for (i = 0; i < nextIdx; i++) {
  254. if ((memZero[i].addr < addr) ||
  255. ((size_t)memZero[i].addr >= (size_t)addr + len)) {
  256. /* Check address not part of memory to check. */
  257. continue;
  258. }
  259. /* Address is in range of memory being freed - check each byte zero. */
  260. for (j = 0; j < memZero[i].len; j++) {
  261. if (((unsigned char*)memZero[i].addr)[j] != 0) {
  262. /* Byte not zero - abort! */
  263. fprintf(stderr, "\n[MEM_ZERO] %s:%p + %ld is not zero\n",
  264. memZero[i].name, memZero[i].addr, j);
  265. fprintf(stderr, "[MEM_ZERO] Checking %p:%ld\n", addr, len);
  266. abort();
  267. }
  268. }
  269. /* Update next index to write to. */
  270. nextIdx--;
  271. if (nextIdx > 0) {
  272. /* Remove entry. */
  273. XMEMCPY(memZero + i, memZero + i + 1,
  274. sizeof(MemZero) * (nextIdx - i));
  275. /* Clear out top to make it easier to see what is to be checked. */
  276. XMEMSET(&memZero[nextIdx], 0, sizeof(MemZero));
  277. }
  278. /* Need to check this index again with new data. */
  279. i--;
  280. }
  281. wc_UnLockMutex(&zeroMutex);
  282. }
  283. #endif /* WOLFSSL_CHECK_MEM_ZERO */
  284. #ifdef WOLFSSL_DEBUG_MEMORY
  285. void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line)
  286. #else
  287. void* wolfSSL_Malloc(size_t size)
  288. #endif
  289. {
  290. void* res = 0;
  291. #ifdef WOLFSSL_MEM_FAIL_COUNT
  292. if (!wc_MemFailCount_AllocMem()) {
  293. WOLFSSL_MSG("MemFailCnt: Fail malloc");
  294. return NULL;
  295. }
  296. #endif
  297. #ifdef WOLFSSL_CHECK_MEM_ZERO
  298. /* Space for requested size. */
  299. size += MEM_ALIGN;
  300. #endif
  301. if (malloc_function) {
  302. #ifdef WOLFSSL_DEBUG_MEMORY
  303. res = malloc_function(size, func, line);
  304. #else
  305. res = malloc_function(size);
  306. #endif
  307. }
  308. else {
  309. #ifndef WOLFSSL_NO_MALLOC
  310. #ifdef WOLFSSL_TRAP_MALLOC_SZ
  311. if (size > WOLFSSL_TRAP_MALLOC_SZ) {
  312. WOLFSSL_MSG("Malloc too big!");
  313. return NULL;
  314. }
  315. #endif
  316. res = malloc(size);
  317. #else
  318. WOLFSSL_MSG("No malloc available");
  319. #endif
  320. }
  321. #ifdef WOLFSSL_CHECK_MEM_ZERO
  322. /* Restore size to requested value. */
  323. size -= MEM_ALIGN;
  324. if (res != NULL) {
  325. /* Place size at front of allocated data and move pointer passed it. */
  326. *(size_t*)res = size;
  327. res = ((unsigned char*)res) + MEM_ALIGN;
  328. }
  329. #endif
  330. #ifdef WOLFSSL_DEBUG_MEMORY
  331. #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)
  332. fprintf(stderr, "Alloc: %p -> %u at %s:%u\n", res, (word32)size, func, line);
  333. #else
  334. (void)func;
  335. (void)line;
  336. #endif
  337. #endif
  338. #ifdef WOLFSSL_MALLOC_CHECK
  339. if (res == NULL)
  340. WOLFSSL_MSG("wolfSSL_malloc failed");
  341. #endif
  342. #ifdef WOLFSSL_FORCE_MALLOC_FAIL_TEST
  343. if (res && --gMemFailCount == 0) {
  344. fprintf(stderr, "\n---FORCED MEM FAIL TEST---\n");
  345. if (free_function) {
  346. #ifdef WOLFSSL_DEBUG_MEMORY
  347. free_function(res, func, line);
  348. #else
  349. free_function(res);
  350. #endif
  351. }
  352. else {
  353. free(res); /* clear */
  354. }
  355. gMemFailCount = gMemFailCountSeed; /* reset */
  356. return NULL;
  357. }
  358. #endif
  359. return res;
  360. }
  361. #ifdef WOLFSSL_DEBUG_MEMORY
  362. void wolfSSL_Free(void *ptr, const char* func, unsigned int line)
  363. #else
  364. void wolfSSL_Free(void *ptr)
  365. #endif
  366. {
  367. #ifdef WOLFSSL_DEBUG_MEMORY
  368. #if defined(WOLFSSL_DEBUG_MEMORY_PRINT) && !defined(WOLFSSL_TRACK_MEMORY)
  369. fprintf(stderr, "Free: %p at %s:%u\n", ptr, func, line);
  370. #else
  371. (void)func;
  372. (void)line;
  373. #endif
  374. #endif
  375. #ifdef WOLFSSL_CHECK_MEM_ZERO
  376. /* Move pointer back to originally allocated pointer. */
  377. ptr = ((unsigned char*)ptr) - MEM_ALIGN;
  378. /* Check that the pointer is zero where required. */
  379. wc_MemZero_Check(((unsigned char*)ptr) + MEM_ALIGN, *(size_t*)ptr);
  380. #endif
  381. #ifdef WOLFSSL_MEM_FAIL_COUNT
  382. wc_MemFailCount_FreeMem();
  383. #endif
  384. if (free_function) {
  385. #ifdef WOLFSSL_DEBUG_MEMORY
  386. free_function(ptr, func, line);
  387. #else
  388. free_function(ptr);
  389. #endif
  390. }
  391. else {
  392. #ifndef WOLFSSL_NO_MALLOC
  393. free(ptr);
  394. #else
  395. WOLFSSL_MSG("No free available");
  396. #endif
  397. }
  398. }
  399. #ifdef WOLFSSL_DEBUG_MEMORY
  400. void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line)
  401. #else
  402. void* wolfSSL_Realloc(void *ptr, size_t size)
  403. #endif
  404. {
  405. #ifdef WOLFSSL_CHECK_MEM_ZERO
  406. /* Can't check data that has been freed during realloc.
  407. * Manually allocated new memory, copy data and free original pointer.
  408. */
  409. #ifdef WOLFSSL_DEBUG_MEMORY
  410. void* res = wolfSSL_Malloc(size, func, line);
  411. #else
  412. void* res = wolfSSL_Malloc(size);
  413. #endif
  414. if (ptr != NULL) {
  415. /* Copy the minimum of old and new size. */
  416. size_t copySize = *(size_t*)(((unsigned char*)ptr) - MEM_ALIGN);
  417. if (size < copySize) {
  418. copySize = size;
  419. }
  420. XMEMCPY(res, ptr, copySize);
  421. /* Dispose of old pointer. */
  422. #ifdef WOLFSSL_DEBUG_MEMORY
  423. wolfSSL_Free(ptr, func, line);
  424. #else
  425. wolfSSL_Free(ptr);
  426. #endif
  427. }
  428. /* Return new pointer with data copied into it. */
  429. return res;
  430. #else
  431. void* res = 0;
  432. #ifdef WOLFSSL_MEM_FAIL_COUNT
  433. if (!wc_MemFailCount_AllocMem()) {
  434. WOLFSSL_MSG("MemFailCnt: Fail realloc");
  435. return NULL;
  436. }
  437. #endif
  438. if (realloc_function) {
  439. #ifdef WOLFSSL_DEBUG_MEMORY
  440. res = realloc_function(ptr, size, func, line);
  441. #else
  442. res = realloc_function(ptr, size);
  443. #endif
  444. }
  445. else {
  446. #ifndef WOLFSSL_NO_MALLOC
  447. res = realloc(ptr, size);
  448. #else
  449. WOLFSSL_MSG("No realloc available");
  450. #endif
  451. }
  452. #ifdef WOLFSSL_MEM_FAIL_COUNT
  453. if (ptr != NULL) {
  454. wc_MemFailCount_FreeMem();
  455. }
  456. #endif
  457. return res;
  458. #endif
  459. }
  460. #endif /* WOLFSSL_STATIC_MEMORY */
  461. #ifdef WOLFSSL_STATIC_MEMORY
  462. struct wc_Memory {
  463. byte* buffer;
  464. struct wc_Memory* next;
  465. word32 sz;
  466. };
  467. /* returns amount of memory used on success. On error returns negative value
  468. wc_Memory** list is the list that new buckets are prepended to
  469. */
  470. static int wc_create_memory_buckets(byte* buffer, word32 bufSz,
  471. word32 buckSz, word32 buckNum, wc_Memory** list) {
  472. word32 i;
  473. byte* pt = buffer;
  474. int ret = 0;
  475. word32 memSz = (word32)sizeof(wc_Memory);
  476. word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
  477. /* if not enough space available for bucket size then do not try */
  478. if (buckSz + memSz + padSz > bufSz) {
  479. return ret;
  480. }
  481. for (i = 0; i < buckNum; i++) {
  482. if ((buckSz + memSz + padSz) <= (bufSz - ret)) {
  483. /* create a new struct and set its values */
  484. wc_Memory* mem = (struct wc_Memory*)(pt);
  485. mem->sz = buckSz;
  486. mem->buffer = (byte*)pt + padSz + memSz;
  487. mem->next = NULL;
  488. /* add the newly created struct to front of list */
  489. if (*list == NULL) {
  490. *list = mem;
  491. } else {
  492. mem->next = *list;
  493. *list = mem;
  494. }
  495. /* advance pointer and keep track of memory used */
  496. ret += buckSz + padSz + memSz;
  497. pt += buckSz + padSz + memSz;
  498. }
  499. else {
  500. break; /* not enough space left for more buckets of this size */
  501. }
  502. }
  503. return ret;
  504. }
  505. static int wc_partition_static_memory(byte* buffer, word32 sz, int flag,
  506. WOLFSSL_HEAP* heap)
  507. {
  508. word32 ava = sz;
  509. byte* pt = buffer;
  510. int ret = 0;
  511. word32 memSz = (word32)sizeof(wc_Memory);
  512. word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
  513. WOLFSSL_ENTER("wc_partition_static_memory");
  514. /* align pt */
  515. while ((wc_ptr_t)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
  516. *pt = 0x00;
  517. pt++;
  518. ava--;
  519. }
  520. #ifdef WOLFSSL_DEBUG_MEMORY
  521. fprintf(stderr, "Allocated %d bytes for static memory @ %p\n", ava, pt);
  522. #endif
  523. /* divide into chunks of memory and add them to available list */
  524. while (ava >= (heap->sizeList[0] + padSz + memSz)) {
  525. /* creating only IO buffers from memory passed in, max TLS is 16k */
  526. if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
  527. if ((ret = wc_create_memory_buckets(pt, ava,
  528. WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) {
  529. WOLFSSL_LEAVE("wc_partition_static_memory", ret);
  530. return ret;
  531. }
  532. /* check if no more room left for creating IO buffers */
  533. if (ret == 0) {
  534. break;
  535. }
  536. /* advance pointer in buffer for next buckets and keep track
  537. of how much memory is left available */
  538. pt += ret;
  539. ava -= ret;
  540. }
  541. else {
  542. int i;
  543. /* start at largest and move to smaller buckets */
  544. for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) {
  545. if ((heap->sizeList[i] + padSz + memSz) <= ava) {
  546. if ((ret = wc_create_memory_buckets(pt, ava,
  547. heap->sizeList[i], heap->distList[i],
  548. &(heap->ava[i]))) < 0) {
  549. WOLFSSL_LEAVE("wc_partition_static_memory", ret);
  550. return ret;
  551. }
  552. /* advance pointer in buffer for next buckets and keep track
  553. of how much memory is left available */
  554. pt += ret;
  555. ava -= ret;
  556. }
  557. }
  558. }
  559. }
  560. return 1;
  561. }
  562. static int wc_init_memory_heap(WOLFSSL_HEAP* heap, unsigned int listSz,
  563. const unsigned int* sizeList, const unsigned int* distList)
  564. {
  565. XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP));
  566. XMEMCPY(heap->sizeList, sizeList, listSz * sizeof(sizeList[0]));
  567. XMEMCPY(heap->distList, distList, listSz * sizeof(distList[0]));
  568. if (wc_InitMutex(&(heap->memory_mutex)) != 0) {
  569. WOLFSSL_MSG("Error creating heap memory mutex");
  570. return BAD_MUTEX_E;
  571. }
  572. return 0;
  573. }
  574. int wc_LoadStaticMemory_ex(WOLFSSL_HEAP_HINT** pHint,
  575. unsigned int listSz, const unsigned int* sizeList,
  576. const unsigned int* distList, unsigned char* buf,
  577. unsigned int sz, int flag, int maxSz)
  578. {
  579. WOLFSSL_HEAP* heap = NULL;
  580. WOLFSSL_HEAP_HINT* hint = NULL;
  581. word32 idx = 0;
  582. int ret;
  583. WOLFSSL_ENTER("wc_LoadStaticMemory_ex");
  584. if (pHint == NULL || buf == NULL || listSz > WOLFMEM_MAX_BUCKETS
  585. || sizeList == NULL || distList == NULL) {
  586. return BAD_FUNC_ARG;
  587. }
  588. if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) {
  589. WOLFSSL_MSG("Not enough memory for partition tracking");
  590. return BUFFER_E; /* not enough memory for structures */
  591. }
  592. /* check if hint has already been assigned */
  593. if (*pHint == NULL) {
  594. heap = (WOLFSSL_HEAP*)buf;
  595. idx += sizeof(WOLFSSL_HEAP);
  596. hint = (WOLFSSL_HEAP_HINT*)(buf + idx);
  597. idx += sizeof(WOLFSSL_HEAP_HINT);
  598. ret = wc_init_memory_heap(heap, listSz, sizeList, distList);
  599. if (ret != 0) {
  600. return ret;
  601. }
  602. XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT));
  603. hint->memory = heap;
  604. }
  605. else {
  606. #ifdef WOLFSSL_HEAP_TEST
  607. /* do not load in memory if test has been set */
  608. if (heap == (void*)WOLFSSL_HEAP_TEST) {
  609. return 0;
  610. }
  611. #endif
  612. hint = (WOLFSSL_HEAP_HINT*)(*pHint);
  613. heap = hint->memory;
  614. }
  615. ret = wc_partition_static_memory(buf + idx, sz - idx, flag, heap);
  616. if (ret != 1) {
  617. WOLFSSL_MSG("Error partitioning memory");
  618. return MEMORY_E;
  619. }
  620. /* determine what max applies too */
  621. if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) {
  622. heap->maxIO = maxSz;
  623. }
  624. else { /* general memory used in handshakes */
  625. heap->maxHa = maxSz;
  626. }
  627. heap->flag |= flag;
  628. *pHint = hint;
  629. return 0;
  630. }
  631. int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint,
  632. unsigned char* buf, unsigned int sz, int flag, int maxSz)
  633. {
  634. word32 sizeList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS };
  635. word32 distList[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST };
  636. int ret = 0;
  637. WOLFSSL_ENTER("wc_LoadStaticMemory");
  638. ret = wc_LoadStaticMemory_ex(pHint,
  639. WOLFMEM_DEF_BUCKETS, sizeList, distList,
  640. buf, sz, flag, maxSz);
  641. WOLFSSL_LEAVE("wc_LoadStaticMemory", ret);
  642. return ret;
  643. }
  644. void wc_UnloadStaticMemory(WOLFSSL_HEAP_HINT* heap)
  645. {
  646. WOLFSSL_ENTER("wc_UnloadStaticMemory");
  647. if (heap != NULL && heap->memory != NULL) {
  648. wc_FreeMutex(&heap->memory->memory_mutex);
  649. }
  650. }
  651. /* returns the size of management memory needed for each bucket.
  652. * This is memory that is used to keep track of and align memory buckets. */
  653. int wolfSSL_MemoryPaddingSz(void)
  654. {
  655. word32 memSz = (word32)sizeof(wc_Memory);
  656. word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
  657. return memSz + padSz;
  658. }
  659. /* Used to calculate memory size for optimum use with buckets.
  660. returns the suggested size rounded down to the nearest bucket. */
  661. int wolfSSL_StaticBufferSz_ex(unsigned int listSz,
  662. const unsigned int *sizeList, const unsigned int *distList,
  663. byte* buffer, word32 sz, int flag)
  664. {
  665. word32 ava = sz;
  666. byte* pt = buffer;
  667. word32 memSz = (word32)sizeof(wc_Memory);
  668. word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1);
  669. WOLFSSL_ENTER("wolfSSL_StaticBufferSz_ex");
  670. if (buffer == NULL || listSz > WOLFMEM_MAX_BUCKETS
  671. || sizeList == NULL || distList == NULL) {
  672. return BAD_FUNC_ARG;
  673. }
  674. /* align pt */
  675. while ((wc_ptr_t)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) {
  676. pt++;
  677. ava--;
  678. }
  679. /* creating only IO buffers from memory passed in, max TLS is 16k */
  680. if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) {
  681. if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) {
  682. return 0; /* not enough room for even one bucket */
  683. }
  684. ava = ava % (memSz + padSz + WOLFMEM_IO_SZ);
  685. }
  686. else {
  687. int i, k;
  688. if (ava < (sizeList[0] + padSz + memSz)) {
  689. return 0; /* not enough room for even one bucket */
  690. }
  691. while ((ava >= (sizeList[0] + padSz + memSz)) && (ava > 0)) {
  692. /* start at largest and move to smaller buckets */
  693. for (i = (listSz - 1); i >= 0; i--) {
  694. for (k = distList[i]; k > 0; k--) {
  695. if ((sizeList[i] + padSz + memSz) <= ava) {
  696. ava -= sizeList[i] + padSz + memSz;
  697. }
  698. }
  699. }
  700. }
  701. }
  702. WOLFSSL_LEAVE("wolfSSL_StaticBufferSz_ex", sz - ava);
  703. return sz - ava; /* round down */
  704. }
  705. /* Calls wolfSSL_StaticBufferSz_ex with the static memory pool config
  706. * used by wolfSSL by default. */
  707. int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag)
  708. {
  709. word32 bucketSz[WOLFMEM_DEF_BUCKETS] = {WOLFMEM_BUCKETS};
  710. word32 distList[WOLFMEM_DEF_BUCKETS] = {WOLFMEM_DIST};
  711. return wolfSSL_StaticBufferSz_ex(WOLFMEM_DEF_BUCKETS, bucketSz, distList,
  712. buffer, sz, flag);
  713. }
  714. int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
  715. {
  716. WOLFSSL_MSG("Freeing fixed IO buffer");
  717. /* check if fixed buffer was set */
  718. if (*io == NULL) {
  719. return 1;
  720. }
  721. if (heap == NULL) {
  722. WOLFSSL_MSG("No heap to return fixed IO too");
  723. }
  724. else {
  725. /* put IO buffer back into IO pool */
  726. (*io)->next = heap->io;
  727. heap->io = *io;
  728. *io = NULL;
  729. }
  730. return 1;
  731. }
  732. int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io)
  733. {
  734. WOLFSSL_MSG("Setting fixed IO for SSL");
  735. if (heap == NULL) {
  736. return MEMORY_E;
  737. }
  738. *io = heap->io;
  739. if (*io != NULL) {
  740. heap->io = (*io)->next;
  741. (*io)->next = NULL;
  742. }
  743. else { /* failed to grab an IO buffer */
  744. return 0;
  745. }
  746. return 1;
  747. }
  748. int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats)
  749. {
  750. word32 i;
  751. wc_Memory* pt;
  752. XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS));
  753. stats->totalAlloc = heap->alloc;
  754. stats->totalFr = heap->frAlc;
  755. stats->curAlloc = stats->totalAlloc - stats->totalFr;
  756. stats->maxHa = heap->maxHa;
  757. stats->maxIO = heap->maxIO;
  758. for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
  759. stats->blockSz[i] = heap->sizeList[i];
  760. for (pt = heap->ava[i]; pt != NULL; pt = pt->next) {
  761. stats->avaBlock[i] += 1;
  762. }
  763. }
  764. for (pt = heap->io; pt != NULL; pt = pt->next) {
  765. stats->avaIO++;
  766. }
  767. stats->flag = heap->flag; /* flag used */
  768. return 1;
  769. }
  770. #ifdef WOLFSSL_DEBUG_MEMORY
  771. void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line)
  772. #else
  773. void* wolfSSL_Malloc(size_t size, void* heap, int type)
  774. #endif
  775. {
  776. void* res = 0;
  777. wc_Memory* pt = NULL;
  778. int i;
  779. /* check for testing heap hint was set */
  780. #ifdef WOLFSSL_HEAP_TEST
  781. if (heap == (void*)WOLFSSL_HEAP_TEST) {
  782. return malloc(size);
  783. }
  784. #endif
  785. /* if no heap hint then use dynamic memory*/
  786. if (heap == NULL) {
  787. #ifdef WOLFSSL_HEAP_TEST
  788. /* allow using malloc for creating ctx and method */
  789. if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
  790. type == DYNAMIC_TYPE_CERT_MANAGER) {
  791. WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method");
  792. res = malloc(size);
  793. }
  794. else {
  795. WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC");
  796. res = NULL;
  797. }
  798. #else
  799. #ifndef WOLFSSL_NO_MALLOC
  800. #ifdef FREERTOS
  801. res = pvPortMalloc(size);
  802. #elif defined(WOLFSSL_EMBOS)
  803. res = OS_HEAP_malloc(size);
  804. #else
  805. res = malloc(size);
  806. #endif
  807. #ifdef WOLFSSL_DEBUG_MEMORY
  808. fprintf(stderr, "Alloc: %p -> %u at %s:%d\n", res, (word32)size, func, line);
  809. #endif
  810. #else
  811. WOLFSSL_MSG("No heap hint found to use and no malloc");
  812. #ifdef WOLFSSL_DEBUG_MEMORY
  813. fprintf(stderr, "ERROR: at %s:%d\n", func, line);
  814. #endif
  815. #endif /* WOLFSSL_NO_MALLOC */
  816. #endif /* WOLFSSL_HEAP_TEST */
  817. }
  818. else {
  819. WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
  820. WOLFSSL_HEAP* mem = hint->memory;
  821. if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
  822. WOLFSSL_MSG("Bad memory_mutex lock");
  823. return NULL;
  824. }
  825. /* case of using fixed IO buffers */
  826. if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
  827. (type == DYNAMIC_TYPE_OUT_BUFFER ||
  828. type == DYNAMIC_TYPE_IN_BUFFER)) {
  829. if (type == DYNAMIC_TYPE_OUT_BUFFER) {
  830. pt = hint->outBuf;
  831. }
  832. if (type == DYNAMIC_TYPE_IN_BUFFER) {
  833. pt = hint->inBuf;
  834. }
  835. }
  836. else {
  837. /* check if using IO pool flag */
  838. if (mem->flag & WOLFMEM_IO_POOL &&
  839. (type == DYNAMIC_TYPE_OUT_BUFFER ||
  840. type == DYNAMIC_TYPE_IN_BUFFER)) {
  841. if (mem->io != NULL) {
  842. pt = mem->io;
  843. mem->io = pt->next;
  844. }
  845. }
  846. /* general static memory */
  847. if (pt == NULL) {
  848. for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
  849. if ((word32)size <= mem->sizeList[i]) {
  850. if (mem->ava[i] != NULL) {
  851. pt = mem->ava[i];
  852. mem->ava[i] = pt->next;
  853. break;
  854. }
  855. #ifdef WOLFSSL_DEBUG_STATIC_MEMORY
  856. else {
  857. fprintf(stderr, "Size: %ld, Empty: %d\n", size,
  858. mem->sizeList[i]);
  859. }
  860. #endif
  861. }
  862. }
  863. }
  864. }
  865. if (pt != NULL) {
  866. mem->inUse += pt->sz;
  867. mem->alloc += 1;
  868. res = pt->buffer;
  869. #ifdef WOLFSSL_DEBUG_MEMORY
  870. fprintf(stderr, "Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
  871. #endif
  872. /* keep track of connection statistics if flag is set */
  873. if (mem->flag & WOLFMEM_TRACK_STATS) {
  874. WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
  875. if (stats != NULL) {
  876. stats->curMem += pt->sz;
  877. if (stats->peakMem < stats->curMem) {
  878. stats->peakMem = stats->curMem;
  879. }
  880. stats->curAlloc++;
  881. if (stats->peakAlloc < stats->curAlloc) {
  882. stats->peakAlloc = stats->curAlloc;
  883. }
  884. stats->totalAlloc++;
  885. }
  886. }
  887. }
  888. else {
  889. WOLFSSL_MSG("ERROR ran out of static memory");
  890. #ifdef WOLFSSL_DEBUG_MEMORY
  891. fprintf(stderr, "Looking for %lu bytes at %s:%d\n", size, func, line);
  892. #endif
  893. }
  894. wc_UnLockMutex(&(mem->memory_mutex));
  895. }
  896. #ifdef WOLFSSL_MALLOC_CHECK
  897. if ((wc_ptr_t)res % WOLFSSL_STATIC_ALIGN) {
  898. WOLFSSL_MSG("ERROR memory is not aligned");
  899. res = NULL;
  900. }
  901. #endif
  902. (void)i;
  903. (void)pt;
  904. (void)type;
  905. return res;
  906. }
  907. #ifdef WOLFSSL_DEBUG_MEMORY
  908. void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line)
  909. #else
  910. void wolfSSL_Free(void *ptr, void* heap, int type)
  911. #endif
  912. {
  913. int i;
  914. wc_Memory* pt;
  915. if (ptr) {
  916. /* check for testing heap hint was set */
  917. #ifdef WOLFSSL_HEAP_TEST
  918. if (heap == (void*)WOLFSSL_HEAP_TEST) {
  919. #ifdef WOLFSSL_DEBUG_MEMORY
  920. fprintf(stderr, "Free: %p at %s:%d\n", pt, func, line);
  921. #endif
  922. return free(ptr);
  923. }
  924. #endif
  925. if (heap == NULL) {
  926. #ifdef WOLFSSL_HEAP_TEST
  927. /* allow using malloc for creating ctx and method */
  928. if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD ||
  929. type == DYNAMIC_TYPE_CERT_MANAGER) {
  930. WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method");
  931. }
  932. else {
  933. WOLFSSL_MSG("ERROR null heap hint passed into XFREE");
  934. }
  935. #endif
  936. #ifndef WOLFSSL_NO_MALLOC
  937. #ifdef FREERTOS
  938. vPortFree(ptr);
  939. #elif defined(WOLFSSL_EMBOS)
  940. OS_HEAP_free(ptr);
  941. #else
  942. free(ptr);
  943. #endif
  944. #else
  945. WOLFSSL_MSG("Error trying to call free when turned off");
  946. #endif /* WOLFSSL_NO_MALLOC */
  947. }
  948. else {
  949. WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
  950. WOLFSSL_HEAP* mem = hint->memory;
  951. word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
  952. /* get memory struct and add it to available list */
  953. pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz);
  954. if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
  955. WOLFSSL_MSG("Bad memory_mutex lock");
  956. return;
  957. }
  958. /* case of using fixed IO buffers */
  959. if (mem->flag & WOLFMEM_IO_POOL_FIXED &&
  960. (type == DYNAMIC_TYPE_OUT_BUFFER ||
  961. type == DYNAMIC_TYPE_IN_BUFFER)) {
  962. /* fixed IO pools are free'd at the end of SSL lifetime
  963. using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */
  964. }
  965. else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ &&
  966. (type == DYNAMIC_TYPE_OUT_BUFFER ||
  967. type == DYNAMIC_TYPE_IN_BUFFER)) {
  968. pt->next = mem->io;
  969. mem->io = pt;
  970. }
  971. else { /* general memory free */
  972. for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
  973. if (pt->sz == mem->sizeList[i]) {
  974. pt->next = mem->ava[i];
  975. mem->ava[i] = pt;
  976. break;
  977. }
  978. }
  979. }
  980. mem->inUse -= pt->sz;
  981. mem->frAlc += 1;
  982. #ifdef WOLFSSL_DEBUG_MEMORY
  983. fprintf(stderr, "Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line);
  984. #endif
  985. /* keep track of connection statistics if flag is set */
  986. if (mem->flag & WOLFMEM_TRACK_STATS) {
  987. WOLFSSL_MEM_CONN_STATS* stats = hint->stats;
  988. if (stats != NULL) {
  989. /* avoid under flow */
  990. if (stats->curMem > pt->sz) {
  991. stats->curMem -= pt->sz;
  992. }
  993. else {
  994. stats->curMem = 0;
  995. }
  996. if (stats->curAlloc > 0) {
  997. stats->curAlloc--;
  998. }
  999. stats->totalFr++;
  1000. }
  1001. }
  1002. wc_UnLockMutex(&(mem->memory_mutex));
  1003. }
  1004. }
  1005. (void)i;
  1006. (void)pt;
  1007. (void)type;
  1008. }
  1009. #ifdef WOLFSSL_DEBUG_MEMORY
  1010. void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line)
  1011. #else
  1012. void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type)
  1013. #endif
  1014. {
  1015. void* res = 0;
  1016. wc_Memory* pt = NULL;
  1017. int i;
  1018. /* check for testing heap hint was set */
  1019. #ifdef WOLFSSL_HEAP_TEST
  1020. if (heap == (void*)WOLFSSL_HEAP_TEST) {
  1021. return realloc(ptr, size);
  1022. }
  1023. #endif
  1024. if (heap == NULL) {
  1025. #ifdef WOLFSSL_HEAP_TEST
  1026. WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC");
  1027. #endif
  1028. #ifndef WOLFSSL_NO_MALLOC
  1029. res = realloc(ptr, size);
  1030. #else
  1031. WOLFSSL_MSG("NO heap found to use for realloc");
  1032. #endif /* WOLFSSL_NO_MALLOC */
  1033. }
  1034. else {
  1035. WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap;
  1036. WOLFSSL_HEAP* mem = hint->memory;
  1037. word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1);
  1038. if (ptr == NULL) {
  1039. #ifdef WOLFSSL_DEBUG_MEMORY
  1040. return wolfSSL_Malloc(size, heap, type, func, line);
  1041. #else
  1042. return wolfSSL_Malloc(size, heap, type);
  1043. #endif
  1044. }
  1045. if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
  1046. WOLFSSL_MSG("Bad memory_mutex lock");
  1047. return NULL;
  1048. }
  1049. /* case of using fixed IO buffers or IO pool */
  1050. if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED))
  1051. && (type == DYNAMIC_TYPE_OUT_BUFFER ||
  1052. type == DYNAMIC_TYPE_IN_BUFFER)) {
  1053. /* no realloc, is fixed size */
  1054. pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory));
  1055. if (pt->sz < size) {
  1056. WOLFSSL_MSG("Error IO memory was not large enough");
  1057. res = NULL; /* return NULL in error case */
  1058. }
  1059. res = pt->buffer;
  1060. }
  1061. else {
  1062. /* general memory */
  1063. for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) {
  1064. if ((word32)size <= mem->sizeList[i]) {
  1065. if (mem->ava[i] != NULL) {
  1066. pt = mem->ava[i];
  1067. mem->ava[i] = pt->next;
  1068. break;
  1069. }
  1070. }
  1071. }
  1072. if (pt != NULL && res == NULL) {
  1073. res = pt->buffer;
  1074. /* copy over original information and free ptr */
  1075. word32 prvSz = ((wc_Memory*)((byte*)ptr - padSz -
  1076. sizeof(wc_Memory)))->sz;
  1077. prvSz = (prvSz > pt->sz)? pt->sz: prvSz;
  1078. XMEMCPY(pt->buffer, ptr, prvSz);
  1079. mem->inUse += pt->sz;
  1080. mem->alloc += 1;
  1081. /* free memory that was previously being used */
  1082. wc_UnLockMutex(&(mem->memory_mutex));
  1083. wolfSSL_Free(ptr, heap, type
  1084. #ifdef WOLFSSL_DEBUG_MEMORY
  1085. , func, line
  1086. #endif
  1087. );
  1088. if (wc_LockMutex(&(mem->memory_mutex)) != 0) {
  1089. WOLFSSL_MSG("Bad memory_mutex lock");
  1090. return NULL;
  1091. }
  1092. }
  1093. }
  1094. wc_UnLockMutex(&(mem->memory_mutex));
  1095. }
  1096. #ifdef WOLFSSL_MALLOC_CHECK
  1097. if ((wc_ptr_t)res % WOLFSSL_STATIC_ALIGN) {
  1098. WOLFSSL_MSG("ERROR memory is not aligned");
  1099. res = NULL;
  1100. }
  1101. #endif
  1102. (void)i;
  1103. (void)pt;
  1104. (void)type;
  1105. return res;
  1106. }
  1107. #endif /* WOLFSSL_STATIC_MEMORY */
  1108. #endif /* USE_WOLFSSL_MEMORY */
  1109. #ifdef HAVE_IO_POOL
  1110. /* Example for user io pool, shared build may need definitions in lib proper */
  1111. #include <stdlib.h>
  1112. #ifndef HAVE_THREAD_LS
  1113. #error "Oops, simple I/O pool example needs thread local storage"
  1114. #endif
  1115. /* allow simple per thread in and out pools */
  1116. /* use 17k size since max record size is 16k plus overhead */
  1117. static THREAD_LS_T byte pool_in[17*1024];
  1118. static THREAD_LS_T byte pool_out[17*1024];
  1119. void* XMALLOC(size_t n, void* heap, int type)
  1120. {
  1121. (void)heap;
  1122. if (type == DYNAMIC_TYPE_IN_BUFFER) {
  1123. if (n < sizeof(pool_in))
  1124. return pool_in;
  1125. else
  1126. return NULL;
  1127. }
  1128. if (type == DYNAMIC_TYPE_OUT_BUFFER) {
  1129. if (n < sizeof(pool_out))
  1130. return pool_out;
  1131. else
  1132. return NULL;
  1133. }
  1134. return malloc(n);
  1135. }
  1136. void* XREALLOC(void *p, size_t n, void* heap, int type)
  1137. {
  1138. (void)heap;
  1139. if (type == DYNAMIC_TYPE_IN_BUFFER) {
  1140. if (n < sizeof(pool_in))
  1141. return pool_in;
  1142. else
  1143. return NULL;
  1144. }
  1145. if (type == DYNAMIC_TYPE_OUT_BUFFER) {
  1146. if (n < sizeof(pool_out))
  1147. return pool_out;
  1148. else
  1149. return NULL;
  1150. }
  1151. return realloc(p, n);
  1152. }
  1153. void XFREE(void *p, void* heap, int type)
  1154. {
  1155. (void)heap;
  1156. if (type == DYNAMIC_TYPE_IN_BUFFER)
  1157. return; /* do nothing, static pool */
  1158. if (type == DYNAMIC_TYPE_OUT_BUFFER)
  1159. return; /* do nothing, static pool */
  1160. free(p);
  1161. }
  1162. #endif /* HAVE_IO_POOL */
  1163. #ifdef WOLFSSL_MEMORY_LOG
  1164. void *xmalloc(size_t n, void* heap, int type, const char* func,
  1165. const char* file, unsigned int line)
  1166. {
  1167. void* p = NULL;
  1168. word32* p32;
  1169. #ifdef WOLFSSL_MEM_FAIL_COUNT
  1170. if (!wc_MemFailCount_AllocMem()) {
  1171. WOLFSSL_MSG("MemFailCnt: Fail malloc");
  1172. return NULL;
  1173. }
  1174. #endif
  1175. if (malloc_function) {
  1176. #ifndef WOLFSSL_STATIC_MEMORY
  1177. p32 = malloc_function(n + sizeof(word32) * 4);
  1178. #else
  1179. p32 = malloc_function(n + sizeof(word32) * 4, heap, type);
  1180. #endif
  1181. }
  1182. else
  1183. p32 = malloc(n + sizeof(word32) * 4);
  1184. if (p32 != NULL) {
  1185. p32[0] = (word32)n;
  1186. p = (void*)(p32 + 4);
  1187. fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", p, (word32)n,
  1188. type, func, file, line);
  1189. }
  1190. (void)heap;
  1191. return p;
  1192. }
  1193. void *xrealloc(void *p, size_t n, void* heap, int type, const char* func,
  1194. const char* file, unsigned int line)
  1195. {
  1196. void* newp = NULL;
  1197. word32* p32;
  1198. word32* oldp32 = NULL;
  1199. word32 oldLen;
  1200. #ifdef WOLFSSL_MEM_FAIL_COUNT
  1201. if (!wc_MemFailCount_AllocMem()) {
  1202. WOLFSSL_MSG("MemFailCnt: Fail malloc");
  1203. return NULL;
  1204. }
  1205. #endif
  1206. if (p != NULL) {
  1207. oldp32 = (word32*)p;
  1208. oldp32 -= 4;
  1209. oldLen = oldp32[0];
  1210. }
  1211. if (realloc_function) {
  1212. #ifndef WOLFSSL_STATIC_MEMORY
  1213. p32 = realloc_function(oldp32, n + sizeof(word32) * 4);
  1214. #else
  1215. p32 = realloc_function(oldp32, n + sizeof(word32) * 4, heap, type);
  1216. #endif
  1217. }
  1218. else
  1219. p32 = realloc(oldp32, n + sizeof(word32) * 4);
  1220. if (p32 != NULL) {
  1221. p32[0] = (word32)n;
  1222. newp = (void*)(p32 + 4);
  1223. if (p != NULL) {
  1224. fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, oldLen,
  1225. type, func, file, line);
  1226. }
  1227. fprintf(stderr, "Alloc: %p -> %u (%d) at %s:%s:%u\n", newp, (word32)n,
  1228. type, func, file, line);
  1229. }
  1230. #ifdef WOLFSSL_MEM_FAIL_COUNT
  1231. if (p != NULL) {
  1232. wc_MemFailCount_FreeMem();
  1233. }
  1234. #endif
  1235. (void)heap;
  1236. return newp;
  1237. }
  1238. void xfree(void *p, void* heap, int type, const char* func, const char* file,
  1239. unsigned int line)
  1240. {
  1241. word32* p32 = (word32*)p;
  1242. if (p != NULL) {
  1243. #ifdef WOLFSSL_MEM_FAIL_COUNT
  1244. wc_MemFailCount_FreeMem();
  1245. #endif
  1246. p32 -= 4;
  1247. fprintf(stderr, "Free: %p -> %u (%d) at %s:%s:%u\n", p, p32[0], type,
  1248. func, file, line);
  1249. if (free_function) {
  1250. #ifndef WOLFSSL_STATIC_MEMORY
  1251. free_function(p32);
  1252. #else
  1253. free_function(p32, heap, type);
  1254. #endif
  1255. }
  1256. else
  1257. free(p32);
  1258. }
  1259. (void)heap;
  1260. }
  1261. #endif /* WOLFSSL_MEMORY_LOG */
  1262. #ifdef WOLFSSL_STACK_LOG
  1263. /* Note: this code only works with GCC using -finstrument-functions. */
  1264. void __attribute__((no_instrument_function))
  1265. __cyg_profile_func_enter(void *func, void *caller)
  1266. {
  1267. register void* sp asm("sp");
  1268. fprintf(stderr, "ENTER: %016lx %p\n", (unsigned long)(wc_ptr_t)func, sp);
  1269. (void)caller;
  1270. }
  1271. void __attribute__((no_instrument_function))
  1272. __cyg_profile_func_exit(void *func, void *caller)
  1273. {
  1274. register void* sp asm("sp");
  1275. fprintf(stderr, "EXIT: %016lx %p\n", (unsigned long)(wc_ptr_t)func, sp);
  1276. (void)caller;
  1277. }
  1278. #endif
  1279. #ifdef WC_DEBUG_CIPHER_LIFECYCLE
  1280. static const byte wc_debug_cipher_lifecycle_tag_value[] =
  1281. { 'W', 'o', 'l', 'f' };
  1282. WOLFSSL_LOCAL int wc_debug_CipherLifecycleInit(
  1283. void **CipherLifecycleTag,
  1284. void *heap)
  1285. {
  1286. if (CipherLifecycleTag == NULL)
  1287. return BAD_FUNC_ARG;
  1288. *CipherLifecycleTag = (void *)XMALLOC(
  1289. sizeof(wc_debug_cipher_lifecycle_tag_value),
  1290. heap,
  1291. DYNAMIC_TYPE_DEBUG_TAG);
  1292. if (*CipherLifecycleTag == NULL)
  1293. return MEMORY_E;
  1294. XMEMCPY(*CipherLifecycleTag,
  1295. wc_debug_cipher_lifecycle_tag_value,
  1296. sizeof(wc_debug_cipher_lifecycle_tag_value));
  1297. return 0;
  1298. }
  1299. WOLFSSL_LOCAL int wc_debug_CipherLifecycleCheck(
  1300. void *CipherLifecycleTag,
  1301. int abort_p)
  1302. {
  1303. int ret;
  1304. if (CipherLifecycleTag == NULL) {
  1305. ret = BAD_STATE_E;
  1306. goto out;
  1307. }
  1308. if (XMEMCMP(CipherLifecycleTag,
  1309. wc_debug_cipher_lifecycle_tag_value,
  1310. sizeof(wc_debug_cipher_lifecycle_tag_value)) != 0)
  1311. {
  1312. ret = BAD_STATE_E;
  1313. goto out;
  1314. }
  1315. ret = 0;
  1316. out:
  1317. if ((ret < 0) && abort_p)
  1318. abort();
  1319. return ret;
  1320. }
  1321. WOLFSSL_LOCAL int wc_debug_CipherLifecycleFree(
  1322. void **CipherLifecycleTag,
  1323. void *heap,
  1324. int abort_p)
  1325. {
  1326. int ret;
  1327. if (CipherLifecycleTag == NULL)
  1328. return BAD_FUNC_ARG;
  1329. ret = wc_debug_CipherLifecycleCheck(*CipherLifecycleTag, abort_p);
  1330. if (ret != 0)
  1331. return ret;
  1332. XFREE(*CipherLifecycleTag, heap, DYNAMIC_TYPE_DEBUG_TAG);
  1333. *CipherLifecycleTag = NULL;
  1334. return 0;
  1335. }
  1336. #endif /* WC_DEBUG_CIPHER_LIFECYCLE */
  1337. #ifdef DEBUG_VECTOR_REGISTER_ACCESS
  1338. THREAD_LS_T int wc_svr_count = 0;
  1339. THREAD_LS_T const char *wc_svr_last_file = NULL;
  1340. THREAD_LS_T int wc_svr_last_line = -1;
  1341. THREAD_LS_T int wc_debug_vector_registers_retval =
  1342. WC_DEBUG_VECTOR_REGISTERS_RETVAL_INITVAL;
  1343. #endif
  1344. #ifdef DEBUG_VECTOR_REGISTER_ACCESS_FUZZING
  1345. #ifdef HAVE_THREAD_LS
  1346. WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) {
  1347. static THREAD_LS_T struct drand48_data wc_svr_fuzzing_state;
  1348. static THREAD_LS_T int wc_svr_fuzzing_seeded = 0;
  1349. long result;
  1350. #ifdef DEBUG_VECTOR_REGISTER_ACCESS
  1351. if (wc_debug_vector_registers_retval)
  1352. return wc_debug_vector_registers_retval;
  1353. #endif
  1354. if (wc_svr_fuzzing_seeded == 0) {
  1355. long seed = WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED;
  1356. char *seed_envstr = getenv("WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED");
  1357. if (seed_envstr)
  1358. seed = strtol(seed_envstr, NULL, 0);
  1359. (void)srand48_r(seed, &wc_svr_fuzzing_state);
  1360. wc_svr_fuzzing_seeded = 1;
  1361. }
  1362. (void)lrand48_r(&wc_svr_fuzzing_state, &result);
  1363. if (result & 1)
  1364. return IO_FAILED_E;
  1365. else
  1366. return 0;
  1367. }
  1368. #else /* !HAVE_THREAD_LS */
  1369. /* alternate implementation useful for testing in the kernel module build, where
  1370. * glibc and thread-local storage are unavailable.
  1371. *
  1372. * note this is not a well-behaved PRNG, but is adequate for fuzzing purposes.
  1373. * the prn sequence is incompressible according to ent and xz, and does not
  1374. * cycle within 10M iterations with various seeds including zero, but the Chi
  1375. * square distribution is poor, and the unconditioned lsb bit balance is ~54%
  1376. * regardless of seed.
  1377. *
  1378. * deterministic only if access is single-threaded, but never degenerate.
  1379. */
  1380. WOLFSSL_LOCAL int SAVE_VECTOR_REGISTERS2_fuzzer(void) {
  1381. static unsigned long prn = WC_DEBUG_VECTOR_REGISTERS_FUZZING_SEED;
  1382. static int balance_bit = 0;
  1383. unsigned long new_prn = prn ^ 0xba86943da66ee701ul; /* note this magic
  1384. * random number is
  1385. * bit-balanced.
  1386. */
  1387. #ifdef DEBUG_VECTOR_REGISTER_ACCESS
  1388. if (wc_debug_vector_registers_retval)
  1389. return wc_debug_vector_registers_retval;
  1390. #endif
  1391. /* barrel-roll using the bottom 6 bits. */
  1392. if (new_prn & 0x3f)
  1393. new_prn = (new_prn << (new_prn & 0x3f)) |
  1394. (new_prn >> (0x40 - (new_prn & 0x3f)));
  1395. prn = new_prn;
  1396. balance_bit = !balance_bit;
  1397. return ((prn & 1) ^ balance_bit) ? IO_FAILED_E : 0;
  1398. }
  1399. #endif /* !HAVE_THREAD_LS */
  1400. #endif /* DEBUG_VECTOR_REGISTER_ACCESS_FUZZING */
  1401. #ifdef WOLFSSL_LINUXKM
  1402. #include "../../linuxkm/linuxkm_memory.c"
  1403. #endif