Fix for CTX free heap hint issue. With openssl extra the param and x509_store.lookup.dirs are allocated at CTX init and if heap or static pool was used depends on ctx->onHeapHint. Added test case for this and inline code comment.

This commit is contained in:
David Garske
2021-10-22 11:55:15 -07:00
parent b5f4a0c005
commit c027fffa92
4 changed files with 78 additions and 58 deletions

View File

@ -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

View File

@ -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) {

View File

@ -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 */

View File

@ -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 */