diff --git a/src/internal.c b/src/internal.c index f8432a153..dccee9684 100644 --- a/src/internal.c +++ b/src/internal.c @@ -2252,13 +2252,25 @@ void wolfSSL_CRYPTO_cleanup_ex_data(WOLFSSL_CRYPTO_EX_DATA* ex_data) } #endif /* HAVE_EX_DATA_CLEANUP_HOOKS */ -/* In case contexts are held in array and don't want to free actual ctx */ +/* In case contexts are held in array and don't want to free actual ctx. */ + +/* The allocations done in InitSSL_Ctx must be free'd with ctx->onHeapHint + * logic. A WOLFSSL_CTX can be assigned a static memory heap hint using + * wolfSSL_CTX_load_static_memory after CTX creation, which means variables + * allocated in InitSSL_Ctx were allocated from heap and should be free'd with + * a NULL heap hint. */ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) { #if defined(HAVE_CERTIFICATE_STATUS_REQUEST_V2) && \ defined(HAVE_TLS_EXTENSIONS) && !defined(NO_WOLFSSL_SERVER) int i; #endif + void* heapAtCTXInit = ctx->heap; +#ifdef WOLFSSL_STATIC_MEMORY + if (ctx->onHeapHint == 0) { + heapAtCTXInit = NULL; + } +#endif #ifdef HAVE_EX_DATA_CLEANUP_HOOKS wolfSSL_CRYPTO_cleanup_ex_data(&ctx->ex_data); @@ -2268,17 +2280,9 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) wolfEventQueue_Free(&ctx->event_queue); #endif /* HAVE_WOLF_EVENT */ -#ifdef WOLFSSL_STATIC_MEMORY - if (ctx->onHeap == 1) { - XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD); - } - else { - XFREE(ctx->method, NULL, DYNAMIC_TYPE_METHOD); - } -#else - XFREE(ctx->method, ctx->heap, DYNAMIC_TYPE_METHOD); -#endif + XFREE(ctx->method, heapAtCTXInit, DYNAMIC_TYPE_METHOD); ctx->method = NULL; + if (ctx->suites) { XFREE(ctx->suites, ctx->heap, DYNAMIC_TYPE_SUITES); ctx->suites = NULL; @@ -2366,7 +2370,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) ctx->alpn_cli_protos = NULL; } if (ctx->param) { - XFREE(ctx->param, ctx->heap, DYNAMIC_TYPE_OPENSSL); + XFREE(ctx->param, heapAtCTXInit, DYNAMIC_TYPE_OPENSSL); ctx->param = NULL; } @@ -2378,7 +2382,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) #endif wc_FreeMutex(&ctx->x509_store.lookup.dirs->lock); - XFREE(ctx->x509_store.lookup.dirs, ctx->heap, DYNAMIC_TYPE_OPENSSL); + XFREE(ctx->x509_store.lookup.dirs, heapAtCTXInit, DYNAMIC_TYPE_OPENSSL); } #endif #ifdef WOLFSSL_STATIC_EPHEMERAL @@ -2395,6 +2399,7 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx) FreeDer(&ctx->staticKE.x25519Key); #endif #endif + (void)heapAtCTXInit; } #ifdef WOLFSSL_STATIC_MEMORY @@ -2418,7 +2423,7 @@ void FreeSSL_Ctx(WOLFSSL_CTX* ctx) int refCount; void* heap = ctx->heap; #ifdef WOLFSSL_STATIC_MEMORY - if (ctx->onHeap == 0) { + if (ctx->onHeapHint == 0) { heap = NULL; } #endif diff --git a/src/ssl.c b/src/ssl.c index b7e77c382..a1f9f7378 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -469,14 +469,14 @@ WOLFSSL_CTX* wolfSSL_CTX_new_ex(WOLFSSL_METHOD* method, void* heap) if (method == NULL) return ctx; - ctx = (WOLFSSL_CTX*) XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX); + ctx = (WOLFSSL_CTX*)XMALLOC(sizeof(WOLFSSL_CTX), heap, DYNAMIC_TYPE_CTX); if (ctx) { int ret; ret = InitSSL_Ctx(ctx, method, heap); #ifdef WOLFSSL_STATIC_MEMORY if (heap != NULL) { - ctx->onHeap = 1; /* free the memory back to heap when done */ + ctx->onHeapHint = 1; /* free the memory back to heap when done */ } #endif if (ret < 0) { diff --git a/tests/api.c b/tests/api.c index f80ffa123..c9dbbcdea 100644 --- a/tests/api.c +++ b/tests/api.c @@ -50418,55 +50418,22 @@ static void test_wolfSSL_CTX_StaticMemory_TLS(int tlsVer, #endif /* WOLFSSL_STATIC_MEMORY && HAVE_IO_TESTS_DEPENDENCIES */ #ifdef WOLFSSL_STATIC_MEMORY - #if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || \ - defined(SESSION_CERTS) - #ifdef OPENSSL_EXTRA - #define TEST_TLS_STATIC_MEMSZ (400000) - #else - #define TEST_TLS_STATIC_MEMSZ (320000) - #endif +#if (defined(HAVE_ECC) && !defined(ALT_ECC_SIZE)) || \ + defined(SESSION_CERTS) + #ifdef OPENSSL_EXTRA + #define TEST_TLS_STATIC_MEMSZ (400000) #else - #define TEST_TLS_STATIC_MEMSZ (80000) + #define TEST_TLS_STATIC_MEMSZ (320000) #endif +#else + #define TEST_TLS_STATIC_MEMSZ (80000) #endif -static void test_wolfSSL_CTX_StaticMemory(void) +static void test_wolfSSL_CTX_StaticMemory_SSL(WOLFSSL_CTX* ctx) { -#ifdef WOLFSSL_STATIC_MEMORY - wolfSSL_method_func method_func; - WOLFSSL_CTX* ctx = NULL; - const int kMaxCtxClients = 2; WOLFSSL *ssl1 = NULL, *ssl2 = NULL, *ssl3 = NULL; WOLFSSL_MEM_STATS mem_stats; WOLFSSL_MEM_CONN_STATS ssl_stats; - #ifdef HAVE_IO_TESTS_DEPENDENCIES - #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) - int tlsVer; - byte cliMem[TEST_TLS_STATIC_MEMSZ]; - #endif - #endif - byte svrMem[TEST_TLS_STATIC_MEMSZ]; - - printf(testingFmt, "test_wolfSSL_CTX_StaticMemory()"); - -#ifndef NO_WOLFSSL_SERVER - #ifndef WOLFSSL_NO_TLS12 - method_func = wolfTLSv1_2_server_method_ex; - #else - method_func = wolfTLSv1_3_server_method_ex; - #endif -#else - #ifndef WOLFSSL_NO_TLS12 - method_func = wolfTLSv1_2_client_method_ex; - #else - method_func = wolfTLSv1_3_client_method_ex; - #endif -#endif - - /* Simple test for static memory with WOLFSSL CTX */ - AssertIntEQ(wolfSSL_CTX_load_static_memory( - &ctx, method_func, svrMem, sizeof(svrMem), - 0, kMaxCtxClients), WOLFSSL_SUCCESS); #if !defined(NO_FILESYSTEM) && !defined(NO_CERTS) && !defined(NO_RSA) AssertIntEQ(wolfSSL_CTX_use_certificate_file(ctx, svrCertFile, @@ -50497,6 +50464,54 @@ static void test_wolfSSL_CTX_StaticMemory(void) wolfSSL_free(ssl1); wolfSSL_free(ssl2); +} +#endif /* WOLFSSL_STATIC_MEMORY */ + +static void test_wolfSSL_CTX_StaticMemory(void) +{ +#ifdef WOLFSSL_STATIC_MEMORY + wolfSSL_method_func method_func; + WOLFSSL_CTX* ctx; + const int kMaxCtxClients = 2; + #ifdef HAVE_IO_TESTS_DEPENDENCIES + #if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) + int tlsVer; + byte cliMem[TEST_TLS_STATIC_MEMSZ]; + #endif + #endif + byte svrMem[TEST_TLS_STATIC_MEMSZ]; + + printf(testingFmt, "test_wolfSSL_CTX_StaticMemory()"); + +#ifndef NO_WOLFSSL_SERVER + #ifndef WOLFSSL_NO_TLS12 + method_func = wolfTLSv1_2_server_method_ex; + #else + method_func = wolfTLSv1_3_server_method_ex; + #endif +#else + #ifndef WOLFSSL_NO_TLS12 + method_func = wolfTLSv1_2_client_method_ex; + #else + method_func = wolfTLSv1_3_client_method_ex; + #endif +#endif + + /* Test creating CTX directly from static memory pool */ + ctx = NULL; + AssertIntEQ(wolfSSL_CTX_load_static_memory( + &ctx, method_func, svrMem, sizeof(svrMem), + 0, kMaxCtxClients), WOLFSSL_SUCCESS); + test_wolfSSL_CTX_StaticMemory_SSL(ctx); + wolfSSL_CTX_free(ctx); + ctx = NULL; + + /* Test for heap allocated CTX, then assigning static pool to it */ + AssertNotNull(ctx = wolfSSL_CTX_new(method_func(NULL))); + AssertIntEQ(wolfSSL_CTX_load_static_memory(&ctx, + NULL, svrMem, sizeof(svrMem), + 0, kMaxCtxClients), WOLFSSL_SUCCESS); + test_wolfSSL_CTX_StaticMemory_SSL(ctx); wolfSSL_CTX_free(ctx); /* TLS Level Tests using static memory */ diff --git a/wolfssl/internal.h b/wolfssl/internal.h index d0e3291da..e2719136d 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -2811,7 +2811,7 @@ struct WOLFSSL_CTX { byte disallowEncThenMac:1; /* Don't do Encrypt-Then-MAC */ #endif #ifdef WOLFSSL_STATIC_MEMORY - byte onHeap:1; /* whether the ctx/method is put on heap hint */ + byte onHeapHint:1; /* whether the ctx/method is put on heap hint */ #endif #ifdef WOLFSSL_MULTICAST byte haveMcast; /* multicast requested */