diff --git a/src/basic/memfd-util.c b/src/basic/memfd-util.c index 99df236e7d..285abd41d3 100644 --- a/src/basic/memfd-util.c +++ b/src/basic/memfd-util.c @@ -65,7 +65,7 @@ int memfd_new(const char *name) { } } - return RET_NERRNO(memfd_create(name, MFD_ALLOW_SEALING | MFD_CLOEXEC)); + return memfd_create_wrapper(name, MFD_ALLOW_SEALING | MFD_CLOEXEC | MFD_NOEXEC_SEAL); } int memfd_map(int fd, uint64_t offset, size_t size, void **p) { diff --git a/src/home/homed-home.c b/src/home/homed-home.c index 413fcf1773..6e9cfd2776 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -23,7 +23,9 @@ #include "home-util.h" #include "homed-home-bus.h" #include "homed-home.h" +#include "memfd-util.h" #include "missing_magic.h" +#include "missing_mman.h" #include "missing_syscall.h" #include "mkdir.h" #include "path-util.h" @@ -1175,9 +1177,9 @@ static int home_start_work(Home *h, const char *verb, UserRecord *hr, UserRecord log_debug("Sending to worker: %s", formatted); - stdout_fd = memfd_create("homework-stdout", MFD_CLOEXEC); + stdout_fd = memfd_create_wrapper("homework-stdout", MFD_CLOEXEC | MFD_NOEXEC_SEAL); if (stdout_fd < 0) - return -errno; + return stdout_fd; r = safe_fork_full("(sd-homework)", (int[]) { stdin_fd, stdout_fd, STDERR_FILENO }, diff --git a/src/shared/data-fd-util.c b/src/shared/data-fd-util.c index 0dbf89293f..4831682a02 100644 --- a/src/shared/data-fd-util.c +++ b/src/shared/data-fd-util.c @@ -339,7 +339,8 @@ finish: int memfd_clone_fd(int fd, const char *name, int mode) { _cleanup_close_ int mfd = -EBADF; - bool ro; + struct stat st; + bool ro, exec; int r; /* Creates a clone of a regular file in a memfd. Unlike copy_data_fd() this returns strictly a memfd @@ -351,14 +352,19 @@ int memfd_clone_fd(int fd, const char *name, int mode) { assert(IN_SET(mode & O_ACCMODE, O_RDONLY, O_RDWR)); assert((mode & ~(O_RDONLY|O_RDWR|O_CLOEXEC)) == 0); - ro = (mode & O_ACCMODE) == O_RDONLY; - - mfd = memfd_create(name, - ((FLAGS_SET(mode, O_CLOEXEC) || ro) ? MFD_CLOEXEC : 0) | - (ro ? MFD_ALLOW_SEALING : 0)); - if (mfd < 0) + if (fstat(fd, &st) < 0) return -errno; + ro = (mode & O_ACCMODE) == O_RDONLY; + exec = st.st_mode & 0111; + + mfd = memfd_create_wrapper(name, + ((FLAGS_SET(mode, O_CLOEXEC) || ro) ? MFD_CLOEXEC : 0) | + (ro ? MFD_ALLOW_SEALING : 0) | + (exec ? MFD_EXEC : MFD_NOEXEC_SEAL)); + if (mfd < 0) + return mfd; + r = copy_bytes(fd, mfd, UINT64_MAX, COPY_REFLINK); if (r < 0) return r; diff --git a/src/shared/serialize.c b/src/shared/serialize.c index cd48286355..9d1a21360f 100644 --- a/src/shared/serialize.c +++ b/src/shared/serialize.c @@ -6,6 +6,7 @@ #include "env-util.h" #include "escape.h" #include "fileio.h" +#include "memfd-util.h" #include "missing_mman.h" #include "missing_syscall.h" #include "parse-util.h" @@ -197,7 +198,7 @@ int deserialize_environment(const char *value, char ***list) { int open_serialization_fd(const char *ident) { int fd; - fd = memfd_create(ident, MFD_CLOEXEC); + fd = memfd_create_wrapper(ident, MFD_CLOEXEC | MFD_NOEXEC_SEAL); if (fd < 0) { const char *path;