>From de4ca3284d759563322c795479601e9eee394832 Mon Sep 17 00:00:00 2001 From: Szabolcs Nagy Date: Sat, 28 Apr 2018 17:25:41 +0000 Subject: [PATCH 9/9] [RFC] add new memory mapping related apis memfd_create (linux v3.17) mlock2 (linux v4.4) pkey_alloc (linux v4.9) pkey_free (linux v4.9) pkey_mprotect (linux v4.9) pkey_get (glibc 2.27) pkey_set (glibc 2.27) notes: - pkey_alloc type is inconsistent between the manual and the glibc source (unsigned int vs unsigned long args) - pkey_get / pkey_set are not syscalls (query/update the pkru register on x86), not implemented yet. - fallback in mlock2 to mlock and pkey_mprotect to mprotect follows glibc. - mlock2 EINVAL return means invalid (or unsupported) flags. - moved MLOCK_ONFAULT under _GNU_SOURCE following glibc. --- arch/powerpc/bits/mman.h | 4 ++++ arch/powerpc64/bits/mman.h | 4 ++++ include/sys/mman.h | 24 +++++++++++++++++++++--- src/linux/memfd_create.c | 10 ++++++++++ src/linux/mlock2.c | 15 +++++++++++++++ src/linux/pkey_alloc.c | 15 +++++++++++++++ src/linux/pkey_get.c | 9 +++++++++ src/linux/pkey_mprotect.c | 15 +++++++++++++++ src/linux/pkey_set.c | 9 +++++++++ 9 files changed, 102 insertions(+), 3 deletions(-) create mode 100644 src/linux/memfd_create.c create mode 100644 src/linux/mlock2.c create mode 100644 src/linux/pkey_alloc.c create mode 100644 src/linux/pkey_get.c create mode 100644 src/linux/pkey_mprotect.c create mode 100644 src/linux/pkey_set.c diff --git a/arch/powerpc/bits/mman.h b/arch/powerpc/bits/mman.h index b3a675a8..23e18eb1 100644 --- a/arch/powerpc/bits/mman.h +++ b/arch/powerpc/bits/mman.h @@ -12,3 +12,7 @@ #define MCL_FUTURE 0x4000 #undef MCL_ONFAULT #define MCL_ONFAULT 0x8000 + +#ifdef _GNU_SOURCE +#define PKEY_DISABLE_EXECUTE 0x4 +#endif diff --git a/arch/powerpc64/bits/mman.h b/arch/powerpc64/bits/mman.h index b3a675a8..23e18eb1 100644 --- a/arch/powerpc64/bits/mman.h +++ b/arch/powerpc64/bits/mman.h @@ -12,3 +12,7 @@ #define MCL_FUTURE 0x4000 #undef MCL_ONFAULT #define MCL_ONFAULT 0x8000 + +#ifdef _GNU_SOURCE +#define PKEY_DISABLE_EXECUTE 0x4 +#endif diff --git a/include/sys/mman.h b/include/sys/mman.h index 302ad134..aea40452 100644 --- a/include/sys/mman.h +++ b/include/sys/mman.h @@ -93,6 +93,20 @@ extern "C" { #define MADV_SOFT_OFFLINE 101 #endif +#ifdef _GNU_SOURCE +#define MREMAP_MAYMOVE 1 +#define MREMAP_FIXED 2 + +#define PKEY_DISABLE_ACCESS 0x1 +#define PKEY_DISABLE_WRITE 0x2 + +#define MLOCK_ONFAULT 0x01 + +#define MFD_CLOEXEC 0x0001U +#define MFD_ALLOW_SEALING 0x0002U +#define MFD_HUGETLB 0x0004U +#endif + #include void *mmap (void *, size_t, int, int, int, off_t); @@ -109,14 +123,18 @@ int mlockall (int); int munlockall (void); #ifdef _GNU_SOURCE -#define MREMAP_MAYMOVE 1 -#define MREMAP_FIXED 2 void *mremap (void *, size_t, size_t, int, ...); int remap_file_pages (void *, size_t, int, size_t, int); +int memfd_create (const char *, unsigned); +int mlock2 (const void *, size_t, unsigned); +int pkey_alloc (unsigned, unsigned); +int pkey_free (int); +int pkey_mprotect (void *, size_t, int, int); +int pkey_get (int); +int pkey_set (int, unsigned); #endif #if defined(_GNU_SOURCE) || defined(_BSD_SOURCE) -#define MLOCK_ONFAULT 0x01 int madvise (void *, size_t, int); int mincore (void *, size_t, unsigned char *); #endif diff --git a/src/linux/memfd_create.c b/src/linux/memfd_create.c new file mode 100644 index 00000000..0b33cc23 --- /dev/null +++ b/src/linux/memfd_create.c @@ -0,0 +1,10 @@ +#include "syscall.h" + +#ifdef SYS_memfd_create +#define _GNU_SOURCE 1 +#include +int memfd_create (const char *name, unsigned flags) +{ + return syscall(SYS_memfd_create, name, flags); +} +#endif diff --git a/src/linux/mlock2.c b/src/linux/mlock2.c new file mode 100644 index 00000000..5cd3fbe7 --- /dev/null +++ b/src/linux/mlock2.c @@ -0,0 +1,15 @@ +#define _GNU_SOURCE 1 +#include +#include +#include "syscall.h" + +int mlock2(const void *addr, size_t len, unsigned flags) +{ + if (flags == 0) + return mlock(addr, len); +#ifdef SYS_mlock2 + return syscall(SYS_mlock2, addr, len, flags); +#else + return __syscall_ret(-EINVAL); +#endif +} diff --git a/src/linux/pkey_alloc.c b/src/linux/pkey_alloc.c new file mode 100644 index 00000000..0b0770a6 --- /dev/null +++ b/src/linux/pkey_alloc.c @@ -0,0 +1,15 @@ +#include "syscall.h" + +#ifdef SYS_pkey_alloc +#define _GNU_SOURCE 1 +#include +int pkey_alloc(unsigned flags, unsigned access) +{ + return syscall(SYS_pkey_alloc, flags, access); +} + +int pkey_free(int pkey) +{ + return syscall(SYS_pkey_free, pkey); +} +#endif diff --git a/src/linux/pkey_get.c b/src/linux/pkey_get.c new file mode 100644 index 00000000..d583fa9c --- /dev/null +++ b/src/linux/pkey_get.c @@ -0,0 +1,9 @@ +#define _GNU_SOURCE 1 +#include +#include +#include "syscall.h" + +int pkey_get(int pkey) +{ + return __syscall_ret(-ENOSYS); +} diff --git a/src/linux/pkey_mprotect.c b/src/linux/pkey_mprotect.c new file mode 100644 index 00000000..dabf9b61 --- /dev/null +++ b/src/linux/pkey_mprotect.c @@ -0,0 +1,15 @@ +#define _GNU_SOURCE 1 +#include +#include +#include "syscall.h" + +int pkey_mprotect(void *addr, size_t len, int prot, int pkey) +{ + if (pkey == -1) + return mprotect(addr, len, prot); +#ifdef SYS_pkey_mprotect + return syscall(SYS_pkey_mprotect, addr, len, prot, pkey); +#else + return __syscall_ret(-EINVAL); +#endif +} diff --git a/src/linux/pkey_set.c b/src/linux/pkey_set.c new file mode 100644 index 00000000..addf8da5 --- /dev/null +++ b/src/linux/pkey_set.c @@ -0,0 +1,9 @@ +#define _GNU_SOURCE 1 +#include +#include +#include "syscall.h" + +int pkey_set(int pkey, unsigned access) +{ + return __syscall_ret(-ENOSYS); +} -- 2.16.3