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