memory.c 41 KB

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