Providing mount in memfd_restricted() syscall
Subsystems (8)
v4 cover Providing mount in memfd_restricted() syscall
Hello,
This patchset builds upon the memfd_restricted() system call that was discussed in the 'KVM: mm: fd-based approach for supporting KVM' patch series, at
https://lore.kernel.org/lkml/[email protected]/T/
The tree can be found at:
https://github.com/googleprodkernel/linux-cc/tree/restrictedmem-provide-mount-fd-rfc-v4
In this patchset, a modification to the memfd_restricted() syscall is proposed, which allows userspace to provide a mount, on which the restrictedmem file will be created and returned from the memfd_restricted().
Allowing userspace to provide a mount allows userspace to control various memory binding policies via tmpfs mount options, such as Transparent HugePage memory allocation policy through 'huge=always/never' and NUMA memory allocation policy through 'mpol=local/bind:*'.
Changes since RFCv3:
+ Added check to ensure that bind mounts must be bind mounts of the whole filesystem
+ Removed inappropriate check on fd’s permissions as Christian suggested
+ Renamed RMFD_USERMNT to MEMFD_RSTD_USERMNT as David suggested
+ Added selftest to check that bind mounts must be bind mounts of the whole filesystem
Changes since RFCv2:
+ Tightened semantics to accept only fds of the root of a tmpfs mount, as Christian suggested
+ Added permissions check on the inode represented by the fd to guard against creation of restrictedmem files on read-only tmpfs filesystems or mounts
+ Renamed RMFD_TMPFILE to RMFD_USERMNT to better represent providing a userspace mount to create a restrictedmem file on
+ Updated selftests for tighter semantics and added selftests to check for permissions
Changes since RFCv1:
+ Use fd to represent mount instead of path string, as Kirill suggested. I believe using fds makes this syscall interface more aligned with the other syscalls like fsopen(), fsconfig(), and fsmount() in terms of using and passing around fds
+ Remove unused variable char *orig_shmem_enabled from selftests
Dependencies:
+ Chao’s work on UPM, at
https://github.com/chao-p/linux/commits/privmem-v11.5
Links to earlier patch series:
+ RFC v3: https://lore.kernel.org/lkml/[email protected]/T/
+ RFC v2: https://lore.kernel.org/lkml/[email protected]/T/
+ RFC v1: https://lore.kernel.org/lkml/[email protected]/T/
Ackerley Tng (2):
mm: restrictedmem: Allow userspace to specify mount for
memfd_restricted
selftests: restrictedmem: Check memfd_restricted()'s handling of
provided userspace mount
include/linux/syscalls.h | 2 +- include/uapi/linux/restrictedmem.h | 8 + mm/restrictedmem.c | 73 ++- tools/testing/selftests/mm/.gitignore | 1 + tools/testing/selftests/mm/Makefile | 1 + .../selftests/mm/memfd_restricted_usermnt.c | 529 ++++++++++++++++++ tools/testing/selftests/mm/run_vmtests.sh | 3 + 7 files changed, 611 insertions(+), 6 deletions(-) create mode 100644 include/uapi/linux/restrictedmem.h create mode 100644 tools/testing/selftests/mm/memfd_restricted_usermnt.c
--
2.40.0.577.gac1e443424-goog
RFC PATCH v4 1/2 mm: restrictedmem: Allow userspace to specify mount for memfd_restricted
By default, the backing shmem file for a restrictedmem fd is created on shmem's kernel space mount.
With this patch, an optional tmpfs mount can be specified via an fd, which will be used as the mountpoint for backing the shmem file associated with a restrictedmem fd.
This will help restrictedmem fds inherit the properties of the provided tmpfs mounts, for example, hugepage (THP) allocation hints, NUMA binding hints, etc.
Permissions for the fd passed to memfd_restricted() is modeled after the openat() syscall, since both of these allow creation of a file upon a mount/directory.
Permission to reference the mount the fd represents is checked upon fd creation by other syscalls (e.g. fsmount(), open(), or open_tree(), etc) and any process that can present memfd_restricted() with a valid fd is expected to have obtained permission to use the mount represented by the fd. This behavior is intended to parallel that of the openat() syscall.
memfd_restricted() will check that the tmpfs superblock is writable, and that the mount is also writable, before attempting to create a restrictedmem file on the mount.
--- include/linux/syscalls.h | 2 +- include/uapi/linux/restrictedmem.h | 8 ++++ mm/restrictedmem.c | 73 ++++++++++++++++++++++++++++-- 3 files changed, 77 insertions(+), 6 deletions(-) create mode 100644 include/uapi/linux/restrictedmem.h
include/linux/syscalls.h +1 -1
@@ -1058,7 +1058,7 @@ asmlinkage long sys_memfd_secret(unsigned int flags);asmlinkage long sys_set_mempolicy_home_node (unsigned long start,unsigned long len,unsigned long home_node,unsigned long flags); -asmlinkage long sys_memfd_restricted (unsigned int flags); +asmlinkage long sys_memfd_restricted (unsigned int flags,int mount_fd);/* * Architecture-specific system calls
include/uapi/linux/restrictedmem.h new file +8 -0
@@ -0,0 +1,8 @@ +/* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ +#ifndef _UAPI_LINUX_RESTRICTEDMEM_H +#define _UAPI_LINUX_RESTRICTEDMEM_H + +/* flags for memfd_restricted */ +#define MEMFD_RSTD_USERMNT 0x0001U + +#endif /* _UAPI_LINUX_RESTRICTEDMEM_H */
mm/restrictedmem.c +68 -5
99 lines not on this page · raw message
Signature · 1 line
2.40.0.577.gac1e443424-goog
RFC PATCH v4 2/2 selftests: restrictedmem: Check memfd_restricted()'s handling of provided userspace mount
In reply to Ackerley TngFor memfd_restricted() calls without a userspace mount, the backing file should be the shmem mount in the kernel, and the size of backing pages should be as defined by system-wide shmem configuration.
If a userspace mount is provided, the size of backing pages should be as defined in the mount.
Also includes negative tests for invalid inputs, including fds representing read-only superblocks/mounts.
--- tools/testing/selftests/mm/.gitignore | 1 + tools/testing/selftests/mm/Makefile | 1 + .../selftests/mm/memfd_restricted_usermnt.c | 529 ++++++++++++++++++ tools/testing/selftests/mm/run_vmtests.sh | 3 + 4 files changed, 534 insertions(+) create mode 100644 tools/testing/selftests/mm/memfd_restricted_usermnt.c
tools/testing/selftests/mm/.gitignore +1 -0
@@ -31,6 +31,7 @@ map_fixed_noreplace write_to_hugetlbfs hmm-tests memfd_restricted +memfd_restricted_usermnt memfd_secret soft-dirty split_huge_page_test
tools/testing/selftests/mm/Makefile +1 -0
@@ -46,6 +46,7 @@ TEST_GEN_FILES += map_fixed_noreplace TEST_GEN_FILES += map_hugetlb TEST_GEN_FILES += map_populate TEST_GEN_FILES += memfd_restricted +TEST_GEN_FILES += memfd_restricted_usermnt TEST_GEN_FILES += memfd_secret TEST_GEN_FILES += migration TEST_GEN_FILES += mlock-random-test
tools/testing/selftests/mm/memfd_restricted_usermnt.c new file +529 -0
529 lines not on this page · raw message
tools/testing/selftests/mm/run_vmtests.sh +3 -0
@@ -40,6 +40,8 @@ separated by spaces: test memadvise(2) MADV_POPULATE_{READ,WRITE} options - memfd_restricted_ test memfd_restricted(2) +- memfd_restricted_usermnt + test memfd_restricted(2)'s handling of provided userspace mounts - memfd_secret test memfd_secret(2) - process_mrelease
@@ -239,6 +241,7 @@ CATEGORY="hmm" run_test ./test_hmm.sh smoke CATEGORY="madv_populate" run_test ./madv_populate CATEGORY="memfd_restricted" run_test ./memfd_restricted +CATEGORY="memfd_restricted_usermnt" run_test ./memfd_restricted_usermnt CATEGORY="memfd_secret" run_test ./memfd_secret
Signature · 1 line
2.40.0.577.gac1e443424-goog