From: Ackerley Tng <[email protected]> Ensure that guest_memfd creation fails with -EINVAL when passed a tmpfs resource pool mount descriptor that has swap enabled, as required by the tmpfs guest_memfd provider implementation.
Signed-off-by: Ackerley Tng <[email protected]> --- tools/testing/selftests/kvm/guest_memfd_test.c | 50 ++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tools/testing/selftests/kvm/guest_memfd_test.c b/tools/testing/selftests/kvm/guest_memfd_test.c index a7a1b5470cb2c..5d017164d7b45 100644 --- a/tools/testing/selftests/kvm/guest_memfd_test.c +++ b/tools/testing/selftests/kvm/guest_memfd_test.c @@ -13,6 +13,7 @@ #include <linux/bitmap.h> #include <linux/falloc.h> +#include <linux/mount.h> #include <linux/sizes.h> #include <sys/types.h> #include <sys/stat.h> @@ -477,6 +478,54 @@ static void test_resource_fd_tmpfs_file(struct kvm_vm *vm) close(file_fd); } +static int create_tmpfs_pool_fd(const char *huge, bool noswap, size_t size) +{ + char size_str[32]; + int fs_fd, mnt_fd; + + TEST_ASSERT(size && IS_ALIGNED(size, page_size), + "Pool size '0x%zx' must be positive and page-aligned", size); + + fs_fd = syscall(__NR_fsopen, "tmpfs", FSOPEN_CLOEXEC); + TEST_ASSERT(fs_fd >= 0, "fsopen failed"); + + if (noswap) + TEST_ASSERT(!syscall(__NR_fsconfig, fs_fd, FSCONFIG_SET_FLAG, + "noswap", NULL, 0), "fsconfig noswap failed"); + + if (huge) + TEST_ASSERT(!syscall(__NR_fsconfig, fs_fd, FSCONFIG_SET_STRING, + "huge", huge, 0), "fsconfig huge failed"); + + snprintf(size_str, sizeof(size_str), "%zu", size); + TEST_ASSERT(!syscall(__NR_fsconfig, fs_fd, FSCONFIG_SET_STRING, + "size", size_str, 0), "fsconfig size failed"); + + TEST_ASSERT(!syscall(__NR_fsconfig, fs_fd, FSCONFIG_CMD_CREATE, + NULL, NULL, 0), "fsconfig create failed"); + + mnt_fd = syscall(__NR_fsmount, fs_fd, FSMOUNT_CLOEXEC, 0); + TEST_ASSERT(mnt_fd > 0, "fsmount failed"); + + close(fs_fd); + return mnt_fd; +} + +static void test_resource_fd_tmpfs_swap(struct kvm_vm *vm) +{ + int pool_fd, fd; + + pool_fd = create_tmpfs_pool_fd("never", false, page_size); + + fd = __vm_create_guest_memfd_resource(vm, page_size, + GUEST_MEMFD_FLAG_USE_RESOURCE, + pool_fd); + TEST_ASSERT(fd < 0, "guest_memfd with swap-enabled tmpfs should fail"); + TEST_ASSERT_EQ(errno, EINVAL); + + close(pool_fd); +} + #define ____gmem_test(__test, __vm, __flags, __gmem_size, args...) \ do { \ int fd = vm_create_guest_memfd(__vm, __gmem_size, __flags); \ @@ -538,6 +587,7 @@ static void test_guest_memfd(unsigned long vm_type) test_resource_fd_invalid(vm); test_resource_fd_unsupported_fs(vm); test_resource_fd_tmpfs_file(vm); + test_resource_fd_tmpfs_swap(vm); __test_guest_memfd(vm, 0); -- 2.56.0.rc1.315.gc6ed9934b7-goog

