summaryrefslogtreecommitdiffstats
path: root/crypto/mem_sec.c
diff options
context:
space:
mode:
authorPauli <paul.dale@oracle.com>2020-02-22 18:39:28 +1000
committerPauli <paul.dale@oracle.com>2020-02-26 15:38:37 +1000
commita998ec0e6e12e03c0d4f922a0fe288d5e054985e (patch)
tree47167c6fd2906a7bd8fdfd14e73d45f68c9f7d02 /crypto/mem_sec.c
parent50e0402c220ab7abd375802ea4264ff3ee9fc339 (diff)
secmem: ignore small minsize arguments to CRYPTO_secure_malloc_init().
If the user specifies a minimum allocation size that is smaller than the free list structure (or zero), calculate the minimum possible size rather than failing. Reviewed-by: Viktor Dukhovni <viktor@openssl.org> (Merged from https://github.com/openssl/openssl/pull/11149)
Diffstat (limited to 'crypto/mem_sec.c')
-rw-r--r--crypto/mem_sec.c28
1 files changed, 22 insertions, 6 deletions
diff --git a/crypto/mem_sec.c b/crypto/mem_sec.c
index 79362c5826..b70c0a97ca 100644
--- a/crypto/mem_sec.c
+++ b/crypto/mem_sec.c
@@ -378,17 +378,33 @@ static int sh_init(size_t size, size_t minsize)
memset(&sh, 0, sizeof(sh));
- /* make sure size and minsize are powers of 2 */
+ /* make sure size is a powers of 2 */
OPENSSL_assert(size > 0);
OPENSSL_assert((size & (size - 1)) == 0);
- OPENSSL_assert((minsize & (minsize - 1)) == 0);
if (size == 0 || (size & (size - 1)) != 0)
goto err;
- if (minsize == 0 || (minsize & (minsize - 1)) != 0)
- goto err;
- while (minsize < sizeof(SH_LIST))
- minsize *= 2;
+ if (minsize <= sizeof(SH_LIST)) {
+ OPENSSL_assert(sizeof(SH_LIST) <= 65536);
+ /*
+ * Compute the minimum possible allocation size.
+ * This must be a power of 2 and at least as large as the SH_LIST
+ * structure.
+ */
+ minsize = sizeof(SH_LIST) - 1;
+ minsize |= minsize >> 1;
+ minsize |= minsize >> 2;
+ if (sizeof(SH_LIST) > 16)
+ minsize |= minsize >> 4;
+ if (sizeof(SH_LIST) > 256)
+ minsize |= minsize >> 8;
+ minsize++;
+ } else {
+ /* make sure minsize is a powers of 2 */
+ OPENSSL_assert((minsize & (minsize - 1)) == 0);
+ if ((minsize & (minsize - 1)) != 0)
+ goto err;
+ }
sh.arena_size = size;
sh.minsize = minsize;