Add support for MLOCK_ONFAULT to secure arena
[openssl.git] / crypto / mem_sec.c
index 4a3f2a84a2175eca14b9b44f3e7f8a2073e53ddc..351dec43bcf032a794d90cb122f7a507ba969d22 100644 (file)
 # 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>
@@ -52,8 +57,8 @@ static CRYPTO_RWLOCK *sec_malloc_lock = NULL;
  * 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);
@@ -433,8 +438,19 @@ static int sh_init(size_t size, int minsize)
     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;
@@ -476,7 +492,7 @@ static char *sh_find_my_buddy(char *ptr, int list)
     return chunk;
 }
 
-static char *sh_malloc(size_t size)
+static void *sh_malloc(size_t size)
 {
     ossl_ssize_t list, slist;
     size_t i;
@@ -535,10 +551,10 @@ static char *sh_malloc(size_t size)
     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;