• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2017  Red Hat, Inc.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it would be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  */
15 
16  /*
17   *  Based on Linux/tools/testing/selftests/memfd/memfd_test.c
18   *  by David Herrmann <dh.herrmann@gmail.com>
19   *
20   *  24/02/2017   Port to LTP    <jracek@redhat.com>
21   */
22 
23 #define _GNU_SOURCE
24 
25 #include <errno.h>
26 
27 #include <tst_test.h>
28 
29 #include "memfd_create_common.h"
30 
31 static char buf[2048];
32 static char term_buf[2048];
33 
34 static int available_flags;
35 
36 static const struct tcase {
37 	char *descr;
38 	char *memfd_name;
39 	int flags;
40 	int memfd_create_exp_err;
41 } tcases[] = {
42 	/*
43 	 * Test memfd_create() syscall
44 	 * Verify syscall-argument validation, including name checks,
45 	 * flag validation and more.
46 	 */
47 	{"invalid name fail 1",   NULL,     0,                      EFAULT },
48 	{"invalid name fail 2",   buf,      0,                      EINVAL },
49 	{"invalid name fail 3",   term_buf, 0,                      EINVAL },
50 
51 	{"invalid flags fail 1", "test",  -500,                     EINVAL },
52 	{"invalid flags fail 2", "test",  0x0100,                   EINVAL },
53 	{"invalid flags fail 3", "test",  ~MFD_CLOEXEC,             EINVAL },
54 	{"invalid flags fail 4", "test",  ~MFD_ALLOW_SEALING,       EINVAL },
55 	{"invalid flags fail 5", "test",  ~0,                       EINVAL },
56 	{"invalid flags fail 6", "test",  0x80000000U,              EINVAL },
57 
58 	{"valid flags 1 pass", "test",  MFD_CLOEXEC,                     0 },
59 	{"valid flags 2 pass", "test",  MFD_ALLOW_SEALING,               0 },
60 	{"valid flags 3 pass", "test",  MFD_CLOEXEC | MFD_ALLOW_SEALING, 0 },
61 	{"valid flags 4 pass", "test",  0,                               0 },
62 	{"valid flags 5 pass", "",      0,                               0 },
63 };
64 
setup(void)65 static void setup(void)
66 {
67 
68 	available_flags = GET_MFD_ALL_AVAILABLE_FLAGS();
69 
70 	memset(buf, 0xff, sizeof(buf));
71 
72 	memset(term_buf, 0xff, sizeof(term_buf));
73 	term_buf[sizeof(term_buf) - 1] = 0;
74 }
75 
verify_memfd_create_errno(unsigned int n)76 static void verify_memfd_create_errno(unsigned int n)
77 {
78 	const struct tcase *tc;
79 	int needed_flags;
80 
81 	tc = &tcases[n];
82 	needed_flags = tc->flags & FLAGS_ALL_MASK;
83 
84 	if ((available_flags & needed_flags) != needed_flags) {
85 		tst_res(TCONF, "test '%s' skipped, flag not implemented",
86 					tc->descr);
87 		return;
88 	}
89 
90 	TEST(sys_memfd_create(tc->memfd_name, tc->flags));
91 	if (TST_ERR != tc->memfd_create_exp_err)
92 		tst_brk(TFAIL, "test '%s'", tc->descr);
93 	else
94 		tst_res(TPASS, "test '%s'", tc->descr);
95 
96 	if (TST_RET > 0)
97 		SAFE_CLOSE(TST_RET);
98 }
99 
100 static struct tst_test test = {
101 	.test = verify_memfd_create_errno,
102 	.tcnt = ARRAY_SIZE(tcases),
103 	.setup = setup,
104 };
105