From 423a033ba7bf9b38a4843ae9609019cc108647cf Mon Sep 17 00:00:00 2001 From: Kyle Evans Date: Fri, 10 Jul 2020 00:45:16 +0000 Subject: [PATCH] memfd_create: turn on SHM_GROW_ON_WRITE memfd_create fds will no longer require an ftruncate(2) to set the size; they'll grow (to the extent that it's possible) upon write(2)-like syscalls. Reviewed by: kib Differential Revision: https://reviews.freebsd.org/D25502 --- lib/libc/sys/shm_open.c | 2 +- sys/compat/linux/linux_file.c | 2 +- tests/sys/kern/memfd_test.c | 17 +++++++++++++---- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/lib/libc/sys/shm_open.c b/lib/libc/sys/shm_open.c index 7eb546552c30..cf89505b3d56 100644 --- a/lib/libc/sys/shm_open.c +++ b/lib/libc/sys/shm_open.c @@ -84,7 +84,7 @@ memfd_create(const char *name, unsigned int flags) /* We've already validated that we're sufficiently sized. */ snprintf(memfd_name, NAME_MAX + 1, "%s%s", MEMFD_NAME_PREFIX, name); oflags = O_RDWR; - shmflags = 0; + shmflags = SHM_GROW_ON_WRITE; if ((flags & MFD_CLOEXEC) != 0) oflags |= O_CLOEXEC; if ((flags & MFD_ALLOW_SEALING) != 0) diff --git a/sys/compat/linux/linux_file.c b/sys/compat/linux/linux_file.c index c4160983bcec..377e0ef4d34a 100644 --- a/sys/compat/linux/linux_file.c +++ b/sys/compat/linux/linux_file.c @@ -1758,7 +1758,7 @@ linux_memfd_create(struct thread *td, struct linux_memfd_create_args *args) if ((flags & MFD_HUGETLB) != 0) return (ENOSYS); oflags = O_RDWR; - shmflags = 0; + shmflags = SHM_GROW_ON_WRITE; if ((flags & MFD_CLOEXEC) != 0) oflags |= O_CLOEXEC; if ((flags & MFD_ALLOW_SEALING) != 0) diff --git a/tests/sys/kern/memfd_test.c b/tests/sys/kern/memfd_test.c index 5d5b8f9e6084..3784c4f0c840 100644 --- a/tests/sys/kern/memfd_test.c +++ b/tests/sys/kern/memfd_test.c @@ -30,6 +30,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -38,18 +39,26 @@ __FBSDID("$FreeBSD$"); ATF_TC_WITHOUT_HEAD(basic); ATF_TC_BODY(basic, tc) { + struct stat sb; int fd; char buf[8]; ATF_REQUIRE((fd = memfd_create("...", 0)) != -1); - /* File size should be initially 0 */ - ATF_REQUIRE(write(fd, buf, sizeof(buf)) == 0); + /* write(2) should grow us out automatically. */ + ATF_REQUIRE(write(fd, buf, sizeof(buf)) == sizeof(buf)); + ATF_REQUIRE(fstat(fd, &sb) == 0); + ATF_REQUIRE(sb.st_size == sizeof(buf)); /* ftruncate(2) must succeed without seals */ - ATF_REQUIRE(ftruncate(fd, sizeof(buf) - 1) == 0); + ATF_REQUIRE(ftruncate(fd, 2 * (sizeof(buf) - 1)) == 0); - ATF_REQUIRE(write(fd, buf, sizeof(buf)) == sizeof(buf) - 1); + /* write(2) again must not be limited by ftruncate(2) size. */ + ATF_REQUIRE(write(fd, buf, sizeof(buf)) == sizeof(buf)); + + /* Sanity check. */ + ATF_REQUIRE(fstat(fd, &sb) == 0); + ATF_REQUIRE(sb.st_size == 2 * sizeof(buf)); close(fd); }