diff options
-rw-r--r-- | crypto/mem_sec.c | 15 | ||||
-rw-r--r-- | test/secmemtest.c | 21 |
2 files changed, 33 insertions, 3 deletions
diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c index 351dec43bc..774b696057 100644 --- a/crypto/mem_sec.c +++ b/crypto/mem_sec.c @@ -73,8 +73,12 @@ int CRYPTO_secure_malloc_init(size_t size, int minsize) sec_malloc_lock = CRYPTO_THREAD_lock_new(); if (sec_malloc_lock == NULL) return 0; - ret = sh_init(size, minsize); - secure_mem_initialized = 1; + if ((ret = sh_init(size, minsize)) != 0) { + secure_mem_initialized = 1; + } else { + CRYPTO_THREAD_lock_free(sec_malloc_lock); + sec_malloc_lock = NULL; + } } return ret; @@ -90,6 +94,7 @@ int CRYPTO_secure_malloc_done() sh_done(); secure_mem_initialized = 0; CRYPTO_THREAD_lock_free(sec_malloc_lock); + sec_malloc_lock = NULL; return 1; } #endif /* IMPLEMENTED */ @@ -341,7 +346,8 @@ static void sh_remove_from_list(char *ptr) static int sh_init(size_t size, int minsize) { - int i, ret; + int ret; + size_t i; size_t pgsize; size_t aligned; @@ -498,6 +504,9 @@ static void *sh_malloc(size_t size) size_t i; char *chunk; + if (size > sh.arena_size) + return NULL; + list = sh.freelist_size - 1; for (i = sh.minsize; i < size; i <<= 1) list--; diff --git a/test/secmemtest.c b/test/secmemtest.c index 3244d06b12..c92db50ace 100644 --- a/test/secmemtest.c +++ b/test/secmemtest.c @@ -61,6 +61,27 @@ static int test_sec_mem(void) || !TEST_true(CRYPTO_secure_malloc_done()) || !TEST_false(CRYPTO_secure_malloc_initialized())) goto end; + + TEST_info("Possible infinite loop: allocate more than available"); + if (!TEST_true(CRYPTO_secure_malloc_init(32768, 16))) + goto end; + TEST_ptr_null(OPENSSL_secure_malloc((size_t)-1)); + TEST_true(CRYPTO_secure_malloc_done()); + + TEST_info("Possible infinite loop: small arena"); + if (!TEST_false(CRYPTO_secure_malloc_init(16, 16))) + goto end; + TEST_false(CRYPTO_secure_malloc_initialized()); + TEST_ptr_null(OPENSSL_secure_malloc((size_t)-1)); + TEST_true(CRYPTO_secure_malloc_done()); + + if (sizeof(size_t) > 4) { + TEST_info("Possible infinite loop: 1<<31 limit"); + if (!TEST_true(CRYPTO_secure_malloc_init((size_t)1<<34, (size_t)1<<4) != 0)) + goto end; + TEST_true(CRYPTO_secure_malloc_done()); + } + /* this can complete - it was not really secure */ testresult = 1; end: |