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



Reply via email to