1 /*
2 * Check decoding of landlock_add_rule syscall.
3 *
4 * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
5 * Copyright (c) 2021-2023 The strace developers.
6 * All rights reserved.
7 *
8 * SPDX-License-Identifier: GPL-2.0-or-later
9 */
10
11 #include "tests.h"
12 #include "scno.h"
13
14 #include <inttypes.h>
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <unistd.h>
18
19 #include <linux/landlock.h>
20
21 #ifndef SKIP_IF_PROC_IS_UNAVAILABLE
22 # define SKIP_IF_PROC_IS_UNAVAILABLE
23 #endif
24
25 #ifndef FD0_STR
26 # define FD0_STR ""
27 #endif
28 #ifndef RULESET_FD
29 # define RULESET_FD -1
30 #endif
31 #ifndef RULESET_FD_STR
32 # define RULESET_FD_STR "-1"
33 #endif
34 #ifndef PARENT_FD
35 # define PARENT_FD -1
36 #endif
37 #ifndef PARENT_FD_STR
38 # define PARENT_FD_STR "-1"
39 #endif
40
41 static const char *errstr;
42
43 static long
44 sys_landlock_add_rule(int ruleset_fd, unsigned int rule_type, void *rule_attr,
45 unsigned int flags)
46 {
47 static const kernel_ulong_t fill =
48 (kernel_ulong_t) 0xd1efaced00000000ULL;
49 kernel_ulong_t arg1 = fill | (unsigned int) ruleset_fd;
50 kernel_ulong_t arg2 = fill | rule_type;
51 kernel_ulong_t arg3 = (uintptr_t) rule_attr;
52 kernel_ulong_t arg4 = fill | flags;
53 kernel_ulong_t arg5 = fill | 0xdecaffed;
54 kernel_ulong_t arg6 = fill | 0xdeefaced;
55
56 long rc = syscall(__NR_landlock_add_rule,
57 arg1, arg2, arg3, arg4, arg5, arg6);
58 errstr = sprintrc(rc);
59 return rc;
60 }
61
62 int
63 main(void)
64 {
65 SKIP_IF_PROC_IS_UNAVAILABLE;
66
67 TAIL_ALLOC_OBJECT_VAR_PTR(struct landlock_path_beneath_attr, attr);
68
69 /* All zeroes */
70 sys_landlock_add_rule(0, 0, NULL, 0);
71 printf("landlock_add_rule(0" FD0_STR ", 0 /* LANDLOCK_RULE_??? */"
72 ", NULL, 0) = %s\n", errstr);
73
74 /* Bogus values */
75 sys_landlock_add_rule(0xdeadc0de, 0xfacebeef, attr + 1, 1);
76 printf("landlock_add_rule(-559038242"
77 ", 0xfacebeef /* LANDLOCK_RULE_??? */, %p, 0x1) = %s\n",
78 attr + 1, errstr);
79
80 sys_landlock_add_rule(1729, 2, attr + 1, 0xffffffff);
81 printf("landlock_add_rule(1729, 0x2 /* LANDLOCK_RULE_??? */, %p"
82 ", 0xffffffff) = %s\n",
83 attr + 1, errstr);
84
85 /* Invalid pointer */
86 sys_landlock_add_rule(RULESET_FD, LANDLOCK_RULE_PATH_BENEATH,
87 attr + 1, 0);
88 printf("landlock_add_rule(" RULESET_FD_STR
89 ", LANDLOCK_RULE_PATH_BENEATH, %p, 0) = %s\n",
90 attr + 1, errstr);
91
92 /* Short read */
93 sys_landlock_add_rule(RULESET_FD, LANDLOCK_RULE_PATH_BENEATH,
94 (char *) attr + 4, 0);
95 printf("landlock_add_rule(" RULESET_FD_STR
96 ", LANDLOCK_RULE_PATH_BENEATH, %p, 0) = %s\n",
97 (char *) attr + 4, errstr);
98
99 /* Valid attr ptr */
100 static const struct {
101 uint64_t val;
102 const char *str;
103 } attr_vals[] = {
104 { ARG_STR(LANDLOCK_ACCESS_FS_EXECUTE) },
105 { ARG_ULL_STR(LANDLOCK_ACCESS_FS_EXECUTE|LANDLOCK_ACCESS_FS_READ_FILE|LANDLOCK_ACCESS_FS_READ_DIR|LANDLOCK_ACCESS_FS_REMOVE_FILE|LANDLOCK_ACCESS_FS_MAKE_CHAR|LANDLOCK_ACCESS_FS_MAKE_DIR|LANDLOCK_ACCESS_FS_MAKE_SOCK|LANDLOCK_ACCESS_FS_MAKE_FIFO|LANDLOCK_ACCESS_FS_MAKE_BLOCK|LANDLOCK_ACCESS_FS_MAKE_SYM|LANDLOCK_ACCESS_FS_REFER|LANDLOCK_ACCESS_FS_TRUNCATE|0xdebeefeddeca8000) },
106 { ARG_ULL_STR(0xdebeefeddeca8000)
107 " /* LANDLOCK_ACCESS_FS_??? */" },
108 };
109 static const struct {
110 int val;
111 const char *str;
112 } parent_fd_vals[] = {
113 { ARG_STR(-1) },
114 { ARG_STR(11630) },
115 { PARENT_FD, PARENT_FD_STR },
116 };
117 for (size_t i = 0; i < ARRAY_SIZE(attr_vals); i++) {
118 for (size_t j = 0; j < ARRAY_SIZE(parent_fd_vals); j++) {
119 attr->allowed_access = attr_vals[i].val;
120 attr->parent_fd = parent_fd_vals[j].val;
121 sys_landlock_add_rule(RULESET_FD,
122 LANDLOCK_RULE_PATH_BENEATH,
123 attr, 0);
124 printf("landlock_add_rule(" RULESET_FD_STR
125 ", LANDLOCK_RULE_PATH_BENEATH"
126 ", {allowed_access=%s, parent_fd=%s}, 0) = %s\n",
127 attr_vals[i].str, parent_fd_vals[j].str, errstr);
128 }
129 }
130
131 puts("+++ exited with 0 +++");
132 return 0;
133 }