summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--crypto/mem_sec.c15
-rw-r--r--test/secmemtest.c21
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: