diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c index 8e6946642b..92b84f95a6 100644 --- a/src/basic/memfd-util.c +++ b/src/basic/memfd-util.c @@ -68,19 +68,40 @@ int memfd_new(const char *name) { return memfd_create_wrapper(name, MFD_ALLOW_SEALING | MFD_CLOEXEC | MFD_NOEXEC_SEAL); } +int memfd_add_seals(int fd, unsigned int seals) { + assert(fd >= 0); + + return RET_NERRNO(fcntl(fd, F_ADD_SEALS, seals)); +} + +int memfd_get_seals(int fd, unsigned int *ret_seals) { + int r; + + assert(fd >= 0); + + r = RET_NERRNO(fcntl(fd, F_GET_SEALS)); + if (r < 0) + return r; + + if (ret_seals) + *ret_seals = r; + return 0; +} + int memfd_map(int fd, uint64_t offset, size_t size, void **p) { + unsigned int seals; void *q; - int sealed; + int r; assert(fd >= 0); assert(size > 0); assert(p); - sealed = memfd_get_sealed(fd); - if (sealed < 0) - return sealed; + r = memfd_get_seals(fd, &seals); + if (r < 0) + return r; - if (sealed) + if (seals & F_SEAL_WRITE) q = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, offset); else q = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, offset); @@ -92,28 +113,19 @@ int memfd_map(int fd, uint64_t offset, size_t size, void **p) { } int memfd_set_sealed(int fd) { - int r; - - assert(fd >= 0); - - r = RET_NERRNO(fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_EXEC | F_SEAL_SEAL)); - if (r == -EINVAL) /* old kernel ? */ - r = RET_NERRNO(fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL)); - - return r; + return memfd_add_seals(fd, F_SEAL_SEAL | F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE); } int memfd_get_sealed(int fd) { + unsigned int seals; int r; - assert(fd >= 0); - - r = fcntl(fd, F_GET_SEALS); + r = memfd_get_seals(fd, &seals); if (r < 0) - return -errno; + return r; /* We ignore F_SEAL_EXEC here to support older kernels. */ - return FLAGS_SET(r, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE | F_SEAL_SEAL); + return FLAGS_SET(seals, F_SEAL_SHRINK | F_SEAL_GROW | F_SEAL_WRITE); } int memfd_get_size(int fd, uint64_t *sz) { diff --git a/src/basic/memfd-util.h b/src/basic/memfd-util.h index 0fe8e3a3c4..9b2103e0ce 100644 --- a/src/basic/memfd-util.h +++ b/src/basic/memfd-util.h @@ -12,6 +12,8 @@ int memfd_new(const char *name); int memfd_new_and_map(const char *name, size_t sz, void **p); int memfd_new_and_seal(const char *name, const void *data, size_t sz); +int memfd_add_seals(int fd, unsigned int seals); +int memfd_get_seals(int fd, unsigned int *ret_seals); int memfd_map(int fd, uint64_t offset, size_t size, void **p); int memfd_set_sealed(int fd);