1 /*
2 * Check decoding of memfd_secret syscall.
3 *
4 * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include "kernel_fcntl.h"
12 #include "scno.h"
13
14 #include <inttypes.h>
15 #include <errno.h>
16 #include <stdio.h>
17 #include <stdint.h>
18 #include <unistd.h>
19
20 #ifndef RETVAL_INJECTED
21 # define RETVAL_INJECTED 0
22 #endif
23
24 #ifndef SKIP_IF_PROC_IS_UNAVAILABLE
25 # define SKIP_IF_PROC_IS_UNAVAILABLE
26 #endif
27 #ifndef FD_PATH
28 # define FD_PATH ""
29 #endif
30
31 #if RETVAL_INJECTED
32 # define INJ_STR " (INJECTED)\n"
33 # define INJ_FD_STR FD_PATH " (INJECTED)\n"
34 #else /* !RETVAL_INJECTED */
35 # define INJ_STR "\n"
36 # define INJ_FD_STR "\n"
37 #endif /* RETVAL_INJECTED */
38
39 static const char *errstr;
40
41
42 static long
43 sys_memfd_secret(unsigned int flags)
44
45 {
46 static const kernel_ulong_t fill =
47 (kernel_ulong_t) 0xbeefcafe00000000ULL;
48 kernel_ulong_t arg1 = fill | flags;
49 kernel_ulong_t arg2 = fill | 0xdefaeced;
50 kernel_ulong_t arg3 = fill | 0xbabefeed;
51 kernel_ulong_t arg4 = fill | 0xbadbeefd;
52 kernel_ulong_t arg5 = fill | 0xdecaffed;
53 kernel_ulong_t arg6 = fill | 0xdeefaced;
54
55 long rc = syscall(__NR_memfd_secret,
56 arg1, arg2, arg3, arg4, arg5, arg6);
57 errstr = sprintrc(rc);
58
59 return rc;
60 }
61
62 int
63 main(void)
64 {
65 SKIP_IF_PROC_IS_UNAVAILABLE;
66
67 static const struct {
68 int val;
69 const char *str;
70 } flags_vals[] = {
71 { ARG_STR(0) },
72 { ARG_STR(O_CLOEXEC) },
73 /* O_CLOEXEC is either 0x80000, 0x200000, or 0x400000 */
74 { ARG_STR(0xde97face) },
75 { ARG_STR(O_CLOEXEC|0xde97face) },
76 };
77 for (size_t i = 0; i < ARRAY_SIZE(flags_vals); i++) {
78 long rc = sys_memfd_secret(flags_vals[i].val);
79 printf("memfd_secret(%s) = %s%s" INJ_STR,
80 flags_vals[i].str, errstr, rc > 0 ? FD_PATH : "");
81 }
82
83 puts("+++ exited with 0 +++");
84 return 0;
85 }