From: David Rheinsberg Date: Mon, 17 Jul 2023 10:17:56 +0000 (+0200) Subject: basic/memfd: fix memfd_map() seal test X-Git-Tag: v255-rc1~850^2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F28423%2Fhead;p=thirdparty%2Fsystemd.git basic/memfd: fix memfd_map() seal test Private mappings are required when F_SEAL_WRITE is set on a memfd, because otherwise you could end up with writable mappings through mprotect() and other calls. This is a limitation of the kernel implementation, and might be lifted by future extensions. Regardless, the current code tests for the full `is_sealed()` before using MAP_PRIVATE. This might end up using MAP_SHARED for write-sealed memfds, which will be refused by the kernel. Fix this and make memfd_map() check for exactly `F_SEAL_WRITE`. --- diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c index a80d586ffa6..92b84f95a6a 100644 --- a/src/basic/memfd-util.c +++ b/src/basic/memfd-util.c @@ -89,18 +89,19 @@ int memfd_get_seals(int fd, unsigned int *ret_seals) { } 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);