1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /*
3 * Copyright (C) 2017 Red Hat, Inc.
4 */
5
6 /*
7 * Based on Linux/tools/testing/selftests/memfd/memfd_test.c
8 * by David Herrmann <dh.herrmann@gmail.com>
9 *
10 * 24/02/2017 Port to LTP <jracek@redhat.com>
11 */
12
13 #define _GNU_SOURCE
14
15 #include <errno.h>
16
17 #include <tst_test.h>
18
19 #include "memfd_create_common.h"
20
21 static char buf[2048];
22 static char term_buf[2048];
23
24 static int available_flags;
25
26 static const struct tcase {
27 char *descr;
28 char *memfd_name;
29 int flags;
30 int memfd_create_exp_err;
31 } tcases[] = {
32 /*
33 * Test memfd_create() syscall
34 * Verify syscall-argument validation, including name checks,
35 * flag validation and more.
36 */
37 {"invalid name fail 1", NULL, 0, EFAULT },
38 {"invalid name fail 2", buf, 0, EINVAL },
39 {"invalid name fail 3", term_buf, 0, EINVAL },
40
41 {"invalid flags fail 1", "test", -500, EINVAL },
42 {"invalid flags fail 2", "test", 0x0100, EINVAL },
43 {"invalid flags fail 3", "test", ~MFD_CLOEXEC, EINVAL },
44 {"invalid flags fail 4", "test", ~MFD_ALLOW_SEALING, EINVAL },
45 {"invalid flags fail 5", "test", ~0, EINVAL },
46 {"invalid flags fail 6", "test", 0x80000000U, EINVAL },
47
48 {"valid flags 1 pass", "test", MFD_CLOEXEC, 0 },
49 {"valid flags 2 pass", "test", MFD_ALLOW_SEALING, 0 },
50 {"valid flags 3 pass", "test", MFD_CLOEXEC | MFD_ALLOW_SEALING, 0 },
51 {"valid flags 4 pass", "test", 0, 0 },
52 {"valid flags 5 pass", "", 0, 0 },
53 };
54
setup(void)55 static void setup(void)
56 {
57
58 available_flags = GET_MFD_ALL_AVAILABLE_FLAGS();
59
60 memset(buf, 0xff, sizeof(buf));
61
62 memset(term_buf, 0xff, sizeof(term_buf));
63 term_buf[sizeof(term_buf) - 1] = 0;
64 }
65
verify_memfd_create_errno(unsigned int n)66 static void verify_memfd_create_errno(unsigned int n)
67 {
68 const struct tcase *tc;
69 int needed_flags;
70
71 tc = &tcases[n];
72 needed_flags = tc->flags & FLAGS_ALL_MASK;
73
74 if ((available_flags & needed_flags) != needed_flags) {
75 tst_res(TCONF, "test '%s' skipped, flag not implemented",
76 tc->descr);
77 return;
78 }
79
80 TEST(sys_memfd_create(tc->memfd_name, tc->flags));
81 if (TST_ERR != tc->memfd_create_exp_err)
82 tst_brk(TFAIL, "test '%s'", tc->descr);
83 else
84 tst_res(TPASS, "test '%s'", tc->descr);
85
86 if (TST_RET > 0)
87 SAFE_CLOSE(TST_RET);
88 }
89
90 static struct tst_test test = {
91 .test = verify_memfd_create_errno,
92 .tcnt = ARRAY_SIZE(tcases),
93 .setup = setup,
94 };
95