diff options
author | Jack Lloyd <[email protected]> | 2018-12-29 09:02:55 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2018-12-29 09:02:55 -0500 |
commit | ea66df22be95306979199d08eb3dae7316cc661f (patch) | |
tree | 5fdef397b1e380d1c48a99dd206b7768dbe886f9 | |
parent | a92c5905c9a55b03d9dad4fbec530ea948ee5e5a (diff) | |
parent | 752dcf335d06c75605313630f87beaa78db5e50d (diff) |
Merge GH #1798 Use posix_memalign instead of mmap for page locked pool
-rw-r--r-- | doc/manual/side_channels.rst | 19 | ||||
-rw-r--r-- | src/lib/utils/os_utils.cpp | 26 |
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); |