Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of wolfSSL by
memory.c
00001 /* memory.c 00002 * 00003 * Copyright (C) 2006-2016 wolfSSL Inc. 00004 * 00005 * This file is part of wolfSSL. 00006 * 00007 * wolfSSL is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * wolfSSL is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License 00018 * along with this program; if not, write to the Free Software 00019 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA 00020 */ 00021 00022 00023 #ifdef HAVE_CONFIG_H 00024 #include <config.h> 00025 #endif 00026 00027 #include <wolfssl/wolfcrypt/settings.h> 00028 00029 /* check old macros @wc_fips */ 00030 #if defined(USE_CYASSL_MEMORY) && !defined(USE_WOLFSSL_MEMORY) 00031 #define USE_WOLFSSL_MEMORY 00032 #endif 00033 #if defined(CYASSL_MALLOC_CHECK) && !defined(WOLFSSL_MALLOC_CHECK) 00034 #define WOLFSSL_MALLOC_CHECK 00035 #endif 00036 00037 #ifdef USE_WOLFSSL_MEMORY 00038 00039 #include <wolfssl/wolfcrypt/memory.h> 00040 #include <wolfssl/wolfcrypt/error-crypt.h> 00041 #include <wolfssl/wolfcrypt/logging.h> 00042 00043 #if defined(WOLFSSL_MALLOC_CHECK) || defined(WOLFSSL_TRACK_MEMORY_FULL) 00044 #include <stdio.h> 00045 #endif 00046 00047 00048 /* Set these to default values initially. */ 00049 static wolfSSL_Malloc_cb malloc_function = 0; 00050 static wolfSSL_Free_cb free_function = 0; 00051 static wolfSSL_Realloc_cb realloc_function = 0; 00052 00053 int wolfSSL_SetAllocators(wolfSSL_Malloc_cb mf, 00054 wolfSSL_Free_cb ff, 00055 wolfSSL_Realloc_cb rf) 00056 { 00057 int res = 0; 00058 00059 if (mf) 00060 malloc_function = mf; 00061 else 00062 res = BAD_FUNC_ARG; 00063 00064 if (ff) 00065 free_function = ff; 00066 else 00067 res = BAD_FUNC_ARG; 00068 00069 if (rf) 00070 realloc_function = rf; 00071 else 00072 res = BAD_FUNC_ARG; 00073 00074 return res; 00075 } 00076 00077 int wolfSSL_GetAllocators(wolfSSL_Malloc_cb* mf, 00078 wolfSSL_Free_cb* ff, 00079 wolfSSL_Realloc_cb* rf) 00080 { 00081 if (mf) *mf = malloc_function; 00082 if (ff) *ff = free_function; 00083 if (rf) *rf = realloc_function; 00084 return 0; 00085 } 00086 00087 #ifndef WOLFSSL_STATIC_MEMORY 00088 #ifdef WOLFSSL_DEBUG_MEMORY 00089 void* wolfSSL_Malloc(size_t size, const char* func, unsigned int line) 00090 #else 00091 void* wolfSSL_Malloc(size_t size) 00092 #endif 00093 { 00094 void* res = 0; 00095 00096 if (malloc_function) { 00097 #ifdef WOLFSSL_DEBUG_MEMORY 00098 res = malloc_function(size, func, line); 00099 #else 00100 res = malloc_function(size); 00101 #endif 00102 } 00103 else { 00104 res = malloc(size); 00105 } 00106 00107 #ifdef WOLFSSL_MALLOC_CHECK 00108 if (res == NULL) 00109 puts("wolfSSL_malloc failed"); 00110 #endif 00111 00112 return res; 00113 } 00114 00115 #ifdef WOLFSSL_DEBUG_MEMORY 00116 void wolfSSL_Free(void *ptr, const char* func, unsigned int line) 00117 #else 00118 void wolfSSL_Free(void *ptr) 00119 #endif 00120 { 00121 if (free_function) { 00122 #ifdef WOLFSSL_DEBUG_MEMORY 00123 free_function(ptr, func, line); 00124 #else 00125 free_function(ptr); 00126 #endif 00127 } 00128 else { 00129 free(ptr); 00130 } 00131 } 00132 00133 #ifdef WOLFSSL_DEBUG_MEMORY 00134 void* wolfSSL_Realloc(void *ptr, size_t size, const char* func, unsigned int line) 00135 #else 00136 void* wolfSSL_Realloc(void *ptr, size_t size) 00137 #endif 00138 { 00139 void* res = 0; 00140 00141 if (realloc_function) { 00142 #ifdef WOLFSSL_DEBUG_MEMORY 00143 res = realloc_function(ptr, size, func, line); 00144 #else 00145 res = realloc_function(ptr, size); 00146 #endif 00147 } 00148 else { 00149 res = realloc(ptr, size); 00150 } 00151 00152 return res; 00153 } 00154 #endif /* WOLFSSL_STATIC_MEMORY */ 00155 00156 #ifdef WOLFSSL_STATIC_MEMORY 00157 00158 struct wc_Memory { 00159 byte* buffer; 00160 struct wc_Memory* next; 00161 word32 sz; 00162 }; 00163 00164 00165 /* returns amount of memory used on success. On error returns negative value 00166 wc_Memory** list is the list that new buckets are prepended to 00167 */ 00168 static int create_memory_buckets(byte* buffer, word32 bufSz, 00169 word32 buckSz, word32 buckNum, wc_Memory** list) { 00170 word32 i; 00171 byte* pt = buffer; 00172 int ret = 0; 00173 word32 memSz = (word32)sizeof(wc_Memory); 00174 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00175 00176 /* if not enough space available for bucket size then do not try */ 00177 if (buckSz + memSz + padSz > bufSz) { 00178 return ret; 00179 } 00180 00181 for (i = 0; i < buckNum; i++) { 00182 if ((buckSz + memSz + padSz) <= (bufSz - ret)) { 00183 /* create a new struct and set its values */ 00184 wc_Memory* mem = (struct wc_Memory*)(pt); 00185 mem->sz = buckSz; 00186 mem->buffer = (byte*)pt + padSz + memSz; 00187 mem->next = NULL; 00188 00189 /* add the newly created struct to front of list */ 00190 if (*list == NULL) { 00191 *list = mem; 00192 } else { 00193 mem->next = *list; 00194 *list = mem; 00195 } 00196 00197 /* advance pointer and keep track of memory used */ 00198 ret += buckSz + padSz + memSz; 00199 pt += buckSz + padSz + memSz; 00200 } 00201 else { 00202 break; /* not enough space left for more buckets of this size */ 00203 } 00204 } 00205 00206 return ret; 00207 } 00208 00209 int wolfSSL_init_memory_heap(WOLFSSL_HEAP* heap) 00210 { 00211 word32 wc_MemSz[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_BUCKETS }; 00212 word32 wc_Dist[WOLFMEM_DEF_BUCKETS] = { WOLFMEM_DIST }; 00213 00214 if (heap == NULL) { 00215 return BAD_FUNC_ARG; 00216 } 00217 00218 XMEMSET(heap, 0, sizeof(WOLFSSL_HEAP)); 00219 00220 XMEMCPY(heap->sizeList, wc_MemSz, sizeof(wc_MemSz)); 00221 XMEMCPY(heap->distList, wc_Dist, sizeof(wc_Dist)); 00222 00223 if (wc_InitMutex(&(heap->memory_mutex)) != 0) { 00224 WOLFSSL_MSG("Error creating heap memory mutex"); 00225 return BAD_MUTEX_E; 00226 } 00227 00228 return 0; 00229 } 00230 00231 int wc_LoadStaticMemory(WOLFSSL_HEAP_HINT** pHint, 00232 unsigned char* buf, unsigned int sz, int flag, int max) 00233 { 00234 int ret; 00235 WOLFSSL_HEAP* heap; 00236 WOLFSSL_HEAP_HINT* hint; 00237 word32 idx = 0; 00238 00239 if (pHint == NULL || buf == NULL) { 00240 return BAD_FUNC_ARG; 00241 } 00242 00243 if ((sizeof(WOLFSSL_HEAP) + sizeof(WOLFSSL_HEAP_HINT)) > sz - idx) { 00244 return BUFFER_E; /* not enough memory for structures */ 00245 } 00246 00247 /* check if hint has already been assigned */ 00248 if (*pHint == NULL) { 00249 heap = (WOLFSSL_HEAP*)buf; 00250 idx += sizeof(WOLFSSL_HEAP); 00251 hint = (WOLFSSL_HEAP_HINT*)(buf + idx); 00252 idx += sizeof(WOLFSSL_HEAP_HINT); 00253 00254 ret = wolfSSL_init_memory_heap(heap); 00255 if (ret != 0) { 00256 return ret; 00257 } 00258 00259 XMEMSET(hint, 0, sizeof(WOLFSSL_HEAP_HINT)); 00260 hint->memory = heap; 00261 } 00262 else { 00263 #ifdef WOLFSSL_HEAP_TEST 00264 /* do not load in memory if test has been set */ 00265 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00266 return 0; 00267 } 00268 #endif 00269 00270 hint = (WOLFSSL_HEAP_HINT*)(*pHint); 00271 heap = hint->memory; 00272 } 00273 00274 ret = wolfSSL_load_static_memory(buf + idx, sz - idx, flag, heap); 00275 if (ret != 1) { 00276 WOLFSSL_MSG("Error partitioning memory"); 00277 return -1; 00278 } 00279 00280 /* determine what max applies too */ 00281 if ((flag & WOLFMEM_IO_POOL) || (flag & WOLFMEM_IO_POOL_FIXED)) { 00282 heap->maxIO = max; 00283 } 00284 else { /* general memory used in handshakes */ 00285 heap->maxHa = max; 00286 } 00287 00288 heap->flag |= flag; 00289 *pHint = hint; 00290 00291 (void)max; 00292 00293 return 0; 00294 } 00295 00296 int wolfSSL_load_static_memory(byte* buffer, word32 sz, int flag, 00297 WOLFSSL_HEAP* heap) 00298 { 00299 word32 ava = sz; 00300 byte* pt = buffer; 00301 int ret = 0; 00302 word32 memSz = (word32)sizeof(wc_Memory); 00303 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00304 00305 WOLFSSL_ENTER("wolfSSL_load_static_memory"); 00306 00307 if (buffer == NULL) { 00308 return BAD_FUNC_ARG; 00309 } 00310 00311 /* align pt */ 00312 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { 00313 *pt = 0x00; 00314 pt++; 00315 ava--; 00316 } 00317 00318 #ifdef WOLFSSL_DEBUG_MEMORY 00319 printf("Allocated %d bytes for static memory @ %p\n", ava, pt); 00320 #endif 00321 00322 /* devide into chunks of memory and add them to available list */ 00323 while (ava >= (heap->sizeList[0] + padSz + memSz)) { 00324 int i; 00325 /* creating only IO buffers from memory passed in, max TLS is 16k */ 00326 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { 00327 if ((ret = create_memory_buckets(pt, ava, 00328 WOLFMEM_IO_SZ, 1, &(heap->io))) < 0) { 00329 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret); 00330 return ret; 00331 } 00332 00333 /* check if no more room left for creating IO buffers */ 00334 if (ret == 0) { 00335 break; 00336 } 00337 00338 /* advance pointer in buffer for next buckets and keep track 00339 of how much memory is left available */ 00340 pt += ret; 00341 ava -= ret; 00342 } 00343 else { 00344 /* start at largest and move to smaller buckets */ 00345 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { 00346 if ((heap->sizeList[i] + padSz + memSz) <= ava) { 00347 if ((ret = create_memory_buckets(pt, ava, heap->sizeList[i], 00348 heap->distList[i], &(heap->ava[i]))) < 0) { 00349 WOLFSSL_LEAVE("wolfSSL_load_static_memory", ret); 00350 return ret; 00351 } 00352 00353 /* advance pointer in buffer for next buckets and keep track 00354 of how much memory is left available */ 00355 pt += ret; 00356 ava -= ret; 00357 } 00358 } 00359 } 00360 } 00361 00362 return 1; 00363 } 00364 00365 00366 /* returns the size of management memory needed for each bucket. 00367 * This is memory that is used to keep track of and align memory buckets. */ 00368 int wolfSSL_MemoryPaddingSz(void) 00369 { 00370 word32 memSz = (word32)sizeof(wc_Memory); 00371 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00372 return memSz + padSz; 00373 } 00374 00375 00376 /* Used to calculate memory size for optimum use with buckets. 00377 returns the suggested size rounded down to the nearest bucket. */ 00378 int wolfSSL_StaticBufferSz(byte* buffer, word32 sz, int flag) 00379 { 00380 word32 bucketSz[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_BUCKETS}; 00381 word32 distList[WOLFMEM_MAX_BUCKETS] = {WOLFMEM_DIST}; 00382 00383 word32 ava = sz; 00384 byte* pt = buffer; 00385 word32 memSz = (word32)sizeof(wc_Memory); 00386 word32 padSz = -(int)memSz & (WOLFSSL_STATIC_ALIGN - 1); 00387 00388 WOLFSSL_ENTER("wolfSSL_static_size"); 00389 00390 if (buffer == NULL) { 00391 return BAD_FUNC_ARG; 00392 } 00393 00394 /* align pt */ 00395 while ((wolfssl_word)pt % WOLFSSL_STATIC_ALIGN && pt < (buffer + sz)) { 00396 pt++; 00397 ava--; 00398 } 00399 00400 /* creating only IO buffers from memory passed in, max TLS is 16k */ 00401 if (flag & WOLFMEM_IO_POOL || flag & WOLFMEM_IO_POOL_FIXED) { 00402 if (ava < (memSz + padSz + WOLFMEM_IO_SZ)) { 00403 return 0; /* not enough room for even one bucket */ 00404 } 00405 00406 ava = ava % (memSz + padSz + WOLFMEM_IO_SZ); 00407 } 00408 else { 00409 int i, k; 00410 00411 if (ava < (bucketSz[0] + padSz + memSz)) { 00412 return 0; /* not enough room for even one bucket */ 00413 } 00414 00415 while ((ava >= (bucketSz[0] + padSz + memSz)) && (ava > 0)) { 00416 /* start at largest and move to smaller buckets */ 00417 for (i = (WOLFMEM_MAX_BUCKETS - 1); i >= 0; i--) { 00418 for (k = distList[i]; k > 0; k--) { 00419 if ((bucketSz[i] + padSz + memSz) <= ava) { 00420 ava -= bucketSz[i] + padSz + memSz; 00421 } 00422 } 00423 } 00424 } 00425 } 00426 00427 return sz - ava; /* round down */ 00428 } 00429 00430 00431 int FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) 00432 { 00433 WOLFSSL_MSG("Freeing fixed IO buffer"); 00434 00435 /* check if fixed buffer was set */ 00436 if (*io == NULL) { 00437 return 1; 00438 } 00439 00440 if (heap == NULL) { 00441 WOLFSSL_MSG("No heap to return fixed IO too"); 00442 } 00443 else { 00444 /* put IO buffer back into IO pool */ 00445 (*io)->next = heap->io; 00446 heap->io = *io; 00447 *io = NULL; 00448 } 00449 00450 return 1; 00451 } 00452 00453 00454 int SetFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) 00455 { 00456 WOLFSSL_MSG("Setting fixed IO for SSL"); 00457 if (heap == NULL) { 00458 return MEMORY_E; 00459 } 00460 00461 *io = heap->io; 00462 00463 if (*io != NULL) { 00464 heap->io = (*io)->next; 00465 (*io)->next = NULL; 00466 } 00467 else { /* failed to grab an IO buffer */ 00468 return 0; 00469 } 00470 00471 return 1; 00472 } 00473 00474 00475 int wolfSSL_GetMemStats(WOLFSSL_HEAP* heap, WOLFSSL_MEM_STATS* stats) 00476 { 00477 word32 i; 00478 wc_Memory* pt; 00479 00480 XMEMSET(stats, 0, sizeof(WOLFSSL_MEM_STATS)); 00481 00482 stats->totalAlloc = heap->alloc; 00483 stats->totalFr = heap->frAlc; 00484 stats->curAlloc = stats->totalAlloc - stats->totalFr; 00485 stats->maxHa = heap->maxHa; 00486 stats->maxIO = heap->maxIO; 00487 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00488 stats->blockSz[i] = heap->sizeList[i]; 00489 for (pt = heap->ava[i]; pt != NULL; pt = pt->next) { 00490 stats->avaBlock[i] += 1; 00491 } 00492 } 00493 00494 for (pt = heap->io; pt != NULL; pt = pt->next) { 00495 stats->avaIO++; 00496 } 00497 00498 stats->flag = heap->flag; /* flag used */ 00499 00500 return 1; 00501 } 00502 00503 00504 #ifdef WOLFSSL_DEBUG_MEMORY 00505 void* wolfSSL_Malloc(size_t size, void* heap, int type, const char* func, unsigned int line) 00506 #else 00507 void* wolfSSL_Malloc(size_t size, void* heap, int type) 00508 #endif 00509 { 00510 void* res = 0; 00511 wc_Memory* pt = NULL; 00512 int i; 00513 00514 /* check for testing heap hint was set */ 00515 #ifdef WOLFSSL_HEAP_TEST 00516 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00517 return malloc(size); 00518 } 00519 #endif 00520 00521 /* if no heap hint then use dynamic memory*/ 00522 if (heap == NULL) { 00523 #ifdef WOLFSSL_HEAP_TEST 00524 /* allow using malloc for creating ctx and method */ 00525 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD || 00526 type == DYNAMIC_TYPE_CERT_MANAGER) { 00527 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n"); 00528 res = malloc(size); 00529 } 00530 else { 00531 WOLFSSL_MSG("ERROR null heap hint passed into XMALLOC\n"); 00532 res = NULL; 00533 } 00534 #else 00535 #ifndef WOLFSSL_NO_MALLOC 00536 res = malloc(size); 00537 #else 00538 WOLFSSL_MSG("No heap hint found to use and no malloc"); 00539 #endif /* WOLFSSL_NO_MALLOC */ 00540 #endif /* WOLFSSL_HEAP_TEST */ 00541 } 00542 else { 00543 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; 00544 WOLFSSL_HEAP* mem = hint->memory; 00545 00546 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00547 WOLFSSL_MSG("Bad memory_mutex lock"); 00548 return NULL; 00549 } 00550 00551 /* case of using fixed IO buffers */ 00552 if (mem->flag & WOLFMEM_IO_POOL_FIXED && 00553 (type == DYNAMIC_TYPE_OUT_BUFFER || 00554 type == DYNAMIC_TYPE_IN_BUFFER)) { 00555 if (type == DYNAMIC_TYPE_OUT_BUFFER) { 00556 pt = hint->outBuf; 00557 } 00558 if (type == DYNAMIC_TYPE_IN_BUFFER) { 00559 pt = hint->inBuf; 00560 } 00561 } 00562 else { 00563 /* check if using IO pool flag */ 00564 if (mem->flag & WOLFMEM_IO_POOL && 00565 (type == DYNAMIC_TYPE_OUT_BUFFER || 00566 type == DYNAMIC_TYPE_IN_BUFFER)) { 00567 if (mem->io != NULL) { 00568 pt = mem->io; 00569 mem->io = pt->next; 00570 } 00571 } 00572 00573 /* general static memory */ 00574 if (pt == NULL) { 00575 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00576 if ((word32)size < mem->sizeList[i]) { 00577 if (mem->ava[i] != NULL) { 00578 pt = mem->ava[i]; 00579 mem->ava[i] = pt->next; 00580 break; 00581 } 00582 } 00583 } 00584 } 00585 } 00586 00587 if (pt != NULL) { 00588 mem->inUse += pt->sz; 00589 mem->alloc += 1; 00590 res = pt->buffer; 00591 00592 #ifdef WOLFSSL_DEBUG_MEMORY 00593 printf("Alloc: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); 00594 #endif 00595 00596 /* keep track of connection statistics if flag is set */ 00597 if (mem->flag & WOLFMEM_TRACK_STATS) { 00598 WOLFSSL_MEM_CONN_STATS* stats = hint->stats; 00599 if (stats != NULL) { 00600 stats->curMem += pt->sz; 00601 if (stats->peakMem < stats->curMem) { 00602 stats->peakMem = stats->curMem; 00603 } 00604 stats->curAlloc++; 00605 if (stats->peakAlloc < stats->curAlloc) { 00606 stats->peakAlloc = stats->curAlloc; 00607 } 00608 stats->totalAlloc++; 00609 } 00610 } 00611 } 00612 else { 00613 WOLFSSL_MSG("ERROR ran out of static memory"); 00614 } 00615 00616 wc_UnLockMutex(&(mem->memory_mutex)); 00617 } 00618 00619 #ifdef WOLFSSL_MALLOC_CHECK 00620 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) { 00621 WOLFSSL_MSG("ERROR memory is not alligned"); 00622 res = NULL; 00623 } 00624 #endif 00625 00626 00627 (void)i; 00628 (void)pt; 00629 (void)type; 00630 00631 return res; 00632 } 00633 00634 00635 #ifdef WOLFSSL_DEBUG_MEMORY 00636 void wolfSSL_Free(void *ptr, void* heap, int type, const char* func, unsigned int line) 00637 #else 00638 void wolfSSL_Free(void *ptr, void* heap, int type) 00639 #endif 00640 { 00641 int i; 00642 wc_Memory* pt; 00643 00644 if (ptr) { 00645 /* check for testing heap hint was set */ 00646 #ifdef WOLFSSL_HEAP_TEST 00647 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00648 return free(ptr); 00649 } 00650 #endif 00651 00652 if (heap == NULL) { 00653 #ifdef WOLFSSL_HEAP_TEST 00654 /* allow using malloc for creating ctx and method */ 00655 if (type == DYNAMIC_TYPE_CTX || type == DYNAMIC_TYPE_METHOD || 00656 type == DYNAMIC_TYPE_CERT_MANAGER) { 00657 WOLFSSL_MSG("ERROR allowing null heap hint for ctx/method\n"); 00658 } 00659 else { 00660 WOLFSSL_MSG("ERROR null heap hint passed into XFREE\n"); 00661 } 00662 #endif 00663 #ifndef WOLFSSL_NO_MALLOC 00664 free(ptr); 00665 #else 00666 WOLFSSL_MSG("Error trying to call free when turned off"); 00667 #endif /* WOLFSSL_NO_MALLOC */ 00668 } 00669 else { 00670 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; 00671 WOLFSSL_HEAP* mem = hint->memory; 00672 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1); 00673 00674 /* get memory struct and add it to available list */ 00675 pt = (wc_Memory*)((byte*)ptr - sizeof(wc_Memory) - padSz); 00676 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00677 WOLFSSL_MSG("Bad memory_mutex lock"); 00678 return; 00679 } 00680 00681 /* case of using fixed IO buffers */ 00682 if (mem->flag & WOLFMEM_IO_POOL_FIXED && 00683 (type == DYNAMIC_TYPE_OUT_BUFFER || 00684 type == DYNAMIC_TYPE_IN_BUFFER)) { 00685 /* fixed IO pools are free'd at the end of SSL lifetime 00686 using FreeFixedIO(WOLFSSL_HEAP* heap, wc_Memory** io) */ 00687 } 00688 else if (mem->flag & WOLFMEM_IO_POOL && pt->sz == WOLFMEM_IO_SZ && 00689 (type == DYNAMIC_TYPE_OUT_BUFFER || 00690 type == DYNAMIC_TYPE_IN_BUFFER)) { 00691 pt->next = mem->io; 00692 mem->io = pt; 00693 } 00694 else { /* general memory free */ 00695 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00696 if (pt->sz == mem->sizeList[i]) { 00697 pt->next = mem->ava[i]; 00698 mem->ava[i] = pt; 00699 break; 00700 } 00701 } 00702 } 00703 mem->inUse -= pt->sz; 00704 mem->frAlc += 1; 00705 00706 #ifdef WOLFSSL_DEBUG_MEMORY 00707 printf("Free: %p -> %u at %s:%d\n", pt->buffer, pt->sz, func, line); 00708 #endif 00709 00710 /* keep track of connection statistics if flag is set */ 00711 if (mem->flag & WOLFMEM_TRACK_STATS) { 00712 WOLFSSL_MEM_CONN_STATS* stats = hint->stats; 00713 if (stats != NULL) { 00714 /* avoid under flow */ 00715 if (stats->curMem > pt->sz) { 00716 stats->curMem -= pt->sz; 00717 } 00718 else { 00719 stats->curMem = 0; 00720 } 00721 00722 if (stats->curAlloc > 0) { 00723 stats->curAlloc--; 00724 } 00725 stats->totalFr++; 00726 } 00727 } 00728 wc_UnLockMutex(&(mem->memory_mutex)); 00729 } 00730 } 00731 00732 (void)i; 00733 (void)pt; 00734 (void)type; 00735 } 00736 00737 #ifdef WOLFSSL_DEBUG_MEMORY 00738 void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type, const char* func, unsigned int line) 00739 #else 00740 void* wolfSSL_Realloc(void *ptr, size_t size, void* heap, int type) 00741 #endif 00742 { 00743 void* res = 0; 00744 wc_Memory* pt = NULL; 00745 word32 prvSz; 00746 int i; 00747 00748 /* check for testing heap hint was set */ 00749 #ifdef WOLFSSL_HEAP_TEST 00750 if (heap == (void*)WOLFSSL_HEAP_TEST) { 00751 return realloc(ptr, size); 00752 } 00753 #endif 00754 00755 if (heap == NULL) { 00756 #ifdef WOLFSSL_HEAP_TEST 00757 WOLFSSL_MSG("ERROR null heap hint passed in to XREALLOC\n"); 00758 #endif 00759 #ifndef WOLFSSL_NO_MALLOC 00760 res = realloc(ptr, size); 00761 #else 00762 WOLFSSL_MSG("NO heap found to use for realloc"); 00763 #endif /* WOLFSSL_NO_MALLOC */ 00764 } 00765 else { 00766 WOLFSSL_HEAP_HINT* hint = (WOLFSSL_HEAP_HINT*)heap; 00767 WOLFSSL_HEAP* mem = hint->memory; 00768 word32 padSz = -(int)sizeof(wc_Memory) & (WOLFSSL_STATIC_ALIGN - 1); 00769 00770 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00771 WOLFSSL_MSG("Bad memory_mutex lock"); 00772 return NULL; 00773 } 00774 00775 /* case of using fixed IO buffers or IO pool */ 00776 if (((mem->flag & WOLFMEM_IO_POOL)||(mem->flag & WOLFMEM_IO_POOL_FIXED)) 00777 && (type == DYNAMIC_TYPE_OUT_BUFFER || 00778 type == DYNAMIC_TYPE_IN_BUFFER)) { 00779 /* no realloc, is fixed size */ 00780 pt = (wc_Memory*)((byte*)ptr - padSz - sizeof(wc_Memory)); 00781 if (pt->sz < size) { 00782 WOLFSSL_MSG("Error IO memory was not large enough"); 00783 res = NULL; /* return NULL in error case */ 00784 } 00785 res = pt->buffer; 00786 } 00787 else { 00788 /* general memory */ 00789 for (i = 0; i < WOLFMEM_MAX_BUCKETS; i++) { 00790 if ((word32)size < mem->sizeList[i]) { 00791 if (mem->ava[i] != NULL) { 00792 pt = mem->ava[i]; 00793 mem->ava[i] = pt->next; 00794 break; 00795 } 00796 } 00797 } 00798 00799 if (pt != NULL && res == NULL) { 00800 res = pt->buffer; 00801 00802 /* copy over original information and free ptr */ 00803 prvSz = ((wc_Memory*)((byte*)ptr - padSz - 00804 sizeof(wc_Memory)))->sz; 00805 prvSz = (prvSz > pt->sz)? pt->sz: prvSz; 00806 XMEMCPY(pt->buffer, ptr, prvSz); 00807 mem->inUse += pt->sz; 00808 mem->alloc += 1; 00809 00810 /* free memory that was previously being used */ 00811 wc_UnLockMutex(&(mem->memory_mutex)); 00812 wolfSSL_Free(ptr, heap, type 00813 #ifdef WOLFSSL_DEBUG_MEMORY 00814 , func, line 00815 #endif 00816 ); 00817 if (wc_LockMutex(&(mem->memory_mutex)) != 0) { 00818 WOLFSSL_MSG("Bad memory_mutex lock"); 00819 return NULL; 00820 } 00821 } 00822 } 00823 wc_UnLockMutex(&(mem->memory_mutex)); 00824 } 00825 00826 #ifdef WOLFSSL_MALLOC_CHECK 00827 if ((wolfssl_word)res % WOLFSSL_STATIC_ALIGN) { 00828 WOLFSSL_MSG("ERROR memory is not alligned"); 00829 res = NULL; 00830 } 00831 #endif 00832 00833 (void)i; 00834 (void)pt; 00835 (void)type; 00836 00837 return res; 00838 } 00839 #endif /* WOLFSSL_STATIC_MEMORY */ 00840 00841 #endif /* USE_WOLFSSL_MEMORY */ 00842 00843 00844 #ifdef HAVE_IO_POOL 00845 00846 /* Example for user io pool, shared build may need definitions in lib proper */ 00847 00848 #include <wolfssl/wolfcrypt/types.h> 00849 #include <stdlib.h> 00850 00851 #ifndef HAVE_THREAD_LS 00852 #error "Oops, simple I/O pool example needs thread local storage" 00853 #endif 00854 00855 00856 /* allow simple per thread in and out pools */ 00857 /* use 17k size since max record size is 16k plus overhead */ 00858 static THREAD_LS_T byte pool_in[17*1024]; 00859 static THREAD_LS_T byte pool_out[17*1024]; 00860 00861 00862 void* XMALLOC(size_t n, void* heap, int type) 00863 { 00864 (void)heap; 00865 00866 if (type == DYNAMIC_TYPE_IN_BUFFER) { 00867 if (n < sizeof(pool_in)) 00868 return pool_in; 00869 else 00870 return NULL; 00871 } 00872 00873 if (type == DYNAMIC_TYPE_OUT_BUFFER) { 00874 if (n < sizeof(pool_out)) 00875 return pool_out; 00876 else 00877 return NULL; 00878 } 00879 00880 return malloc(n); 00881 } 00882 00883 void* XREALLOC(void *p, size_t n, void* heap, int type) 00884 { 00885 (void)heap; 00886 00887 if (type == DYNAMIC_TYPE_IN_BUFFER) { 00888 if (n < sizeof(pool_in)) 00889 return pool_in; 00890 else 00891 return NULL; 00892 } 00893 00894 if (type == DYNAMIC_TYPE_OUT_BUFFER) { 00895 if (n < sizeof(pool_out)) 00896 return pool_out; 00897 else 00898 return NULL; 00899 } 00900 00901 return realloc(p, n); 00902 } 00903 00904 void XFREE(void *p, void* heap, int type) 00905 { 00906 (void)heap; 00907 00908 if (type == DYNAMIC_TYPE_IN_BUFFER) 00909 return; /* do nothing, static pool */ 00910 00911 if (type == DYNAMIC_TYPE_OUT_BUFFER) 00912 return; /* do nothing, static pool */ 00913 00914 free(p); 00915 } 00916 00917 #endif /* HAVE_IO_POOL */ 00918 00919
Generated on Tue Jul 12 2022 23:30:58 by
 1.7.2 
    