+/*
+ * Copyright 2015-2017 The OpenSSL Project Authors. All Rights Reserved.
+ *
+ * Licensed under the OpenSSL license (the "License"). You may not use
+ * this file except in compliance with the License. You can obtain a copy
+ * in the file LICENSE in the source distribution or at
+ * https://www.openssl.org/source/license.html
+ */
+
/*
* Copyright 2004-2014, Akamai Technologies. All Rights Reserved.
* This file is distributed under the terms of the OpenSSL license.
# include <unistd.h>
# include <sys/types.h>
# include <sys/mman.h>
+# if defined(OPENSSL_SYS_LINUX)
+# include <sys/syscall.h>
+# include <linux/mman.h>
+# include <errno.h>
+# endif
# include <sys/param.h>
# include <sys/stat.h>
# include <fcntl.h>
-# include "internal/threads.h"
#endif
#define CLEAR(p, s) OPENSSL_cleanse(p, s)
* These are the functions that must be implemented by a secure heap (sh).
*/
static int sh_init(size_t size, int minsize);
-static char *sh_malloc(size_t size);
-static void sh_free(char *ptr);
+static void *sh_malloc(size_t size);
+static void sh_free(void *ptr);
static void sh_done(void);
static size_t sh_actual_size(char *ptr);
static int sh_allocated(const char *ptr);
if (minsize <= 0 || (minsize & (minsize - 1)) != 0)
goto err;
+ while (minsize < (int)sizeof(SH_LIST))
+ minsize *= 2;
+
sh.arena_size = size;
sh.minsize = minsize;
sh.bittable_size = (sh.arena_size / sh.minsize) * 2;
+ /* Prevent allocations of size 0 later on */
+ if (sh.bittable_size >> 3 == 0)
+ goto err;
+
sh.freelist_size = -1;
for (i = sh.bittable_size; i; i >>= 1)
sh.freelist_size++;
if (mprotect(sh.map_result + aligned, pgsize, PROT_NONE) < 0)
ret = 2;
+#if defined(OPENSSL_SYS_LINUX) && defined(MLOCK_ONFAULT) && defined(SYS_mlock2)
+ if (syscall(SYS_mlock2, sh.arena, sh.arena_size, MLOCK_ONFAULT) < 0) {
+ if (errno == ENOSYS) {
+ if (mlock(sh.arena, sh.arena_size) < 0)
+ ret = 2;
+ } else {
+ ret = 2;
+ }
+ }
+#else
if (mlock(sh.arena, sh.arena_size) < 0)
ret = 2;
+#endif
#ifdef MADV_DONTDUMP
if (madvise(sh.arena, sh.arena_size, MADV_DONTDUMP) < 0)
ret = 2;
return chunk;
}
-static char *sh_malloc(size_t size)
+static void *sh_malloc(size_t size)
{
ossl_ssize_t list, slist;
size_t i;
return chunk;
}
-static void sh_free(char *ptr)
+static void sh_free(void *ptr)
{
size_t list;
- char *buddy;
+ void *buddy;
if (ptr == NULL)
return;