• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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