aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2018-12-29 09:02:55 -0500
committerJack Lloyd <[email protected]>2018-12-29 09:02:55 -0500
commitea66df22be95306979199d08eb3dae7316cc661f (patch)
tree5fdef397b1e380d1c48a99dd206b7768dbe886f9
parenta92c5905c9a55b03d9dad4fbec530ea948ee5e5a (diff)
parent752dcf335d06c75605313630f87beaa78db5e50d (diff)
Merge GH #1798 Use posix_memalign instead of mmap for page locked pool
-rw-r--r--doc/manual/side_channels.rst19
-rw-r--r--src/lib/utils/os_utils.cpp26
2 files changed, 18 insertions, 27 deletions
diff --git a/doc/manual/side_channels.rst b/doc/manual/side_channels.rst
index f58269d01..f18625911 100644
--- a/doc/manual/side_channels.rst
+++ b/doc/manual/side_channels.rst
@@ -351,8 +351,8 @@ such a way that it is guaranteed that the compiler will not elide the
'additional' (seemingly unnecessary) writes to zero out the memory.
The function secure_scrub_memory (in mem_ops.cpp) uses some system specific
-trick to zero out an array. On Windows it uses the directly supported API
-function RtlSecureZeroMemory.
+trick to zero out an array. If possible an OS provided routine (such as
+``RtlSecureZeroMemory`` or ``explicit_bzero``) is used.
On other platforms, by default the trick of referencing memset through a
volatile function pointer is used. This approach is not guaranteed to work on
@@ -370,16 +370,15 @@ Botan's secure_vector type is a std::vector with a custom allocator. The
allocator calls secure_scrub_memory before freeing memory.
Some operating systems support an API call to lock a range of pages
-into memory, such that they will never be swapped out (mlock on POSIX,
-VirtualLock on Windows). On many POSIX systems mlock is only usable by
+into memory, such that they will never be swapped out (``mlock`` on POSIX,
+``VirtualLock`` on Windows). On many POSIX systems ``mlock`` is only usable by
root, but on Linux, FreeBSD and possibly other systems a small amount
-of memory can be mlock'ed by processes without extra credentials.
+of memory can be locked by processes without extra credentials.
-If available, Botan uses such a region for storing key material. It is
-created in anonymous mapped memory (not disk backed), locked in
-memory, and scrubbed on free. This memory pool is used by
-secure_vector when available. It can be disabled at runtime setting
-the environment variable BOTAN_MLOCK_POOL_SIZE to 0.
+If available, Botan uses such a region for storing key material. A page-aligned
+block of memory is allocated and locked, then the memory is scrubbed before
+freeing. This memory pool is used by secure_vector when available. It can be
+disabled at runtime setting the environment variable BOTAN_MLOCK_POOL_SIZE to 0.
Automated Analysis
---------------------
diff --git a/src/lib/utils/os_utils.cpp b/src/lib/utils/os_utils.cpp
index 558bd71e6..265d4aac2 100644
--- a/src/lib/utils/os_utils.cpp
+++ b/src/lib/utils/os_utils.cpp
@@ -23,6 +23,7 @@
#include <sys/resource.h>
#include <sys/mman.h>
#include <signal.h>
+ #include <stdlib.h>
#include <setjmp.h>
#include <unistd.h>
#include <errno.h>
@@ -331,25 +332,16 @@ void* OS::allocate_locked_pages(size_t length)
{
#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
-#if !defined(MAP_NOCORE)
- #define MAP_NOCORE 0
-#endif
+ const size_t page_size = OS::system_page_size();
-#if !defined(MAP_ANONYMOUS)
- #define MAP_ANONYMOUS MAP_ANON
-#endif
+ if(length % page_size != 0)
+ return nullptr;
- void* ptr = ::mmap(nullptr,
- length,
- PROT_READ | PROT_WRITE,
- MAP_ANONYMOUS | MAP_SHARED | MAP_NOCORE,
- /*fd*/-1,
- /*offset*/0);
+ void* ptr = nullptr;
+ int rc = ::posix_memalign(&ptr, page_size, length);
- if(ptr == MAP_FAILED)
- {
+ if(rc != 0 || ptr == nullptr)
return nullptr;
- }
#if defined(MADV_DONTDUMP)
::madvise(ptr, length, MADV_DONTDUMP);
@@ -357,7 +349,7 @@ void* OS::allocate_locked_pages(size_t length)
if(::mlock(ptr, length) != 0)
{
- ::munmap(ptr, length);
+ std::free(ptr);
return nullptr; // failed to lock
}
@@ -392,7 +384,7 @@ void OS::free_locked_pages(void* ptr, size_t length)
#if defined(BOTAN_TARGET_OS_HAS_POSIX1) && defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK)
secure_scrub_memory(ptr, length);
::munlock(ptr, length);
- ::munmap(ptr, length);
+ std::free(ptr);
#elif defined(BOTAN_TARGET_OS_HAS_VIRTUAL_LOCK)
secure_scrub_memory(ptr, length);