xref: /aosp_15_r20/external/ltp/testcases/kernel/syscalls/memfd_create/memfd_create02.c (revision 49cdfc7efb34551c7342be41a7384b9c40d7cab7)
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