diff options
author | Mike Rapoport <rppt@linux.ibm.com> | 2020-07-20 10:39:57 +0300 |
---|---|---|
committer | Mike Rapoport <rppt@linux.ibm.com> | 2020-07-20 10:39:57 +0300 |
commit | 50a6bf4bda239ce821ea34948d8809d5be085267 (patch) | |
tree | c073c1441ac827adb311ee289781f5128cfdecdf | |
parent | e664743c81fd5ba89b9294b9d4ec665248228581 (diff) | |
download | secret-memory-preloader-secretmemfd.tar.gz |
Add support for dedicated 'secretmemfd' system call.secretmemfd
If this system call is not implemented, retry with
memfd_create(MFD_SECRET).
Signed-off-by: Mike Rapoport <rppt@linux.ibm.com>
-rw-r--r-- | preload.c | 60 |
1 files changed, 47 insertions, 13 deletions
@@ -2,6 +2,7 @@ #include <unistd.h> #include <stdlib.h> #include <string.h> +#include <errno.h> #include <sys/ioctl.h> #include <sys/mman.h> @@ -16,6 +17,10 @@ #define MFD_SECRET_EXCLUSIVE _IOW(MFD_SECRET_IOCTL, 0x13, unsigned long) #define MFD_SECRET_UNCACHED _IOW(MFD_SECRET_IOCTL, 0x14, unsigned long) +/* secretmemfd defines */ +#define SECRETMEM_EXCLUSIVE 0x1 +#define SECRETMEM_UNCACHED 0x2 + #define ASSERT(x) do { if (!(x)) { printf("ASSERTION failed at line %d\n", __LINE__); exit(1); } } while (0) /* glibc should have defined this by now, sigh */ @@ -24,6 +29,46 @@ static inline int memfd_create(const char *name, unsigned int flags) return syscall(__NR_memfd_create, name, flags); } +#ifndef __NR_secretmemfd +#define __NR_secretmemfd 440 +#endif + +static inline int secretmemfd(unsigned long flags) +{ + return syscall(__NR_secretmemfd, flags); +} + +static int use_secret = 1; +static int secret_option = MFD_SECRET_EXCLUSIVE; + +static int secretmem_open(void) +{ + unsigned long secretmemfd_flags = SECRETMEM_EXCLUSIVE; + int fd, ret; + + if (!use_secret) + return memfd_create("secure", MFD_CLOEXEC); + + if (secret_option == MFD_SECRET_UNCACHED) + secretmemfd_flags = SECRETMEM_EXCLUSIVE; + + /* try dedicated syscall first */ + fd = secretmemfd(secretmemfd_flags); + if (fd >= 0 || errno != ENOSYS) + return fd; + + /* secretmemfd is not implemented, maybe memfd_create(SECRET) is */ + fd = memfd_create("secure", MFD_CLOEXEC|MFD_SECRET); + if (fd < 0) + return fd; + + ret = ioctl(fd, secret_option); + if (ret < 0) + return ret; + + return fd; +} + /* segment size. Matches hugepage size */ #define SEG_SIZE 2*1024*1024 @@ -180,9 +225,6 @@ static void show_segment(void) printf("SHOW SEGMENT END\n"); } -static int use_secret = 1; -static int secret_option = MFD_SECRET_EXCLUSIVE; - static void alloc_segment(void) { int fd; @@ -192,16 +234,8 @@ static void alloc_segment(void) const size_t ssize = pad_request(sizeof(*seg)); struct malloc_chunk *c; - if (use_secret) - fd = memfd_create("secure", MFD_CLOEXEC|MFD_SECRET); - else - fd = memfd_create("secure", MFD_CLOEXEC); - check(fd < 0, "memfd_create"); - - if (use_secret) { - ret = ioctl(fd, secret_option); - check(ret < 0, "ioctl"); - } + fd = secretmem_open(); + check(fd < 0, "secretmem_open"); ret = ftruncate(fd, SEG_SIZE); check(ret < 0, "ftruncate"); |