Skip to contentSkip to conversation

Providing mount in memfd_restricted() syscall

RFC PATCH New Ackerley Tng 1 participant 3 messages Apr 11, 2023

Subsystems (8)
lore
Share & tools
lore
#0 lore raw

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

#1 lore raw

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
index 660be0bf89d5..90c73b9e14e5 100644
@@ -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
new file mode 100644
index 000000000000..73e31bce73dc
@@ -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
#2 lore raw

RFC PATCH v4 2/2 selftests: restrictedmem: Check memfd_restricted()'s handling of provided userspace mount

In reply to Ackerley Tng

For 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
index fb6e4233374d..dba320c8151a 100644
@@ -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
index 5ec338ea1fed..2f5df7a12ea5 100644
@@ -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
index 53de84e3ec2c..04238f86f037 100644
@@ -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