1 /*
2 * Check decoding of fsconfig syscall.
3 *
4 * Copyright (c) 2019-2021 Dmitry V. Levin <ldv@strace.io>
5 * All rights reserved.
6 *
7 * SPDX-License-Identifier: GPL-2.0-or-later
8 */
9
10 #include "tests.h"
11 #include "scno.h"
12
13 #include <fcntl.h>
14 #include <limits.h>
15 #include <stdio.h>
16 #include <stdint.h>
17 #include <unistd.h>
18 #include <linux/mount.h>
19
20 static const char *errstr;
21
22 static long
23 k_fsconfig(const unsigned int fs_fd,
24 const unsigned int cmd,
25 const void *key,
26 const void *value,
27 const unsigned int aux)
28 {
29 const kernel_ulong_t fill = (kernel_ulong_t) 0xdefaced00000000ULL;
30 const kernel_ulong_t bad = (kernel_ulong_t) 0xbadc0dedbadc0dedULL;
31 const kernel_ulong_t arg1 = fill | fs_fd;
32 const kernel_ulong_t arg2 = fill | cmd;
33 const kernel_ulong_t arg3 = (uintptr_t) key;
34 const kernel_ulong_t arg4 = (uintptr_t) value;
35 const kernel_ulong_t arg5 = fill | aux;
36 const long rc = syscall(__NR_fsconfig,
37 arg1, arg2, arg3, arg4, arg5, bad);
38 errstr = sprintrc(rc);
39 return rc;
40 }
41
42 static const char path_full[] = "/dev/full";
43 static const int max_string_size = 256;
44 static const int max_blob_size = 300;
45 static const int huge_blob_size = 1024 * 1024 + 1;
46 static const char *fd_path;
47 static const void *efault;
48 static const char *empty;
49 static char *fname;
50 static char *key1;
51 static char *key;
52 static char *val1;
53 static char *val;
54 static char *blob1;
55 static char *blob;
56 static int fd;
57
58 static void
59 test_fsconfig_unknown(void)
60 {
61 k_fsconfig(fd, 8, empty, val, -100);
62 #ifndef PATH_TRACING
63 printf("fsconfig(%d<%s>, 0x8 /* FSCONFIG_??? */, %p, %p, -100) = %s\n",
64 fd, fd_path, empty, val, errstr);
65 #endif
66
67 k_fsconfig(-100, -1, empty, fd_path, fd);
68 #ifndef PATH_TRACING
69 printf("fsconfig(-100, 0xffffffff /* FSCONFIG_??? */, %p, %p, %d)"
70 " = %s\n",
71 empty, fd_path, fd, errstr);
72 #endif
73 }
74
75 static void
76 test_fsconfig_cmd(const unsigned int cmd, const char *cmd_str)
77 {
78 k_fsconfig(fd, cmd, empty, val, -100);
79 #ifndef PATH_TRACING
80 printf("fsconfig(%d<%s>, %s, %p, %p, -100) = %s\n",
81 fd, fd_path, cmd_str, empty, val, errstr);
82 #endif
83
84 k_fsconfig(-100, cmd, empty, fd_path, fd);
85 #ifndef PATH_TRACING
86 printf("fsconfig(-100, %s, %p, %p, %d) = %s\n",
87 cmd_str, empty, fd_path, fd, errstr);
88 #endif
89 }
90
91 static void
92 test_fsconfig_set_flag(const unsigned int cmd, const char *cmd_str)
93 {
94 k_fsconfig(fd, cmd, key, val, -100);
95 #ifndef PATH_TRACING
96 printf("fsconfig(%d<%s>, %s, \"%s\", %p, -100) = %s\n",
97 fd, fd_path, cmd_str, key, val, errstr);
98 #endif
99
100 k_fsconfig(fd, cmd, key1, val, -100);
101 #ifndef PATH_TRACING
102 printf("fsconfig(%d<%s>, %s, \"%.*s\"..., %p, -100) = %s\n",
103 fd, fd_path, cmd_str, max_string_size, key1, val, errstr);
104 #endif
105
106 k_fsconfig(-100, cmd, key, fd_path, fd);
107 #ifndef PATH_TRACING
108 printf("fsconfig(-100, %s, \"%s\", %p, %d) = %s\n",
109 cmd_str, key, fd_path, fd, errstr);
110 #endif
111 }
112
113 static void
114 test_fsconfig_set_string(const unsigned int cmd, const char *cmd_str)
115 {
116 k_fsconfig(fd, cmd, key, val, -100);
117 #ifndef PATH_TRACING
118 printf("fsconfig(%d<%s>, %s, \"%s\", \"%s\", -100) = %s\n",
119 fd, fd_path, cmd_str, key, val, errstr);
120 #endif
121
122 k_fsconfig(fd, cmd, key1, val1, -100);
123 #ifndef PATH_TRACING
124 printf("fsconfig(%d<%s>, %s, \"%.*s\"..., \"%.*s\"..., -100) = %s\n",
125 fd, fd_path, cmd_str, max_string_size, key1, max_string_size, val1,
126 errstr);
127 #endif
128
129 k_fsconfig(-100, cmd, key, fd_path, fd);
130 #ifndef PATH_TRACING
131 printf("fsconfig(-100, %s, \"%s\", \"%s\", %d) = %s\n",
132 cmd_str, key, fd_path, fd, errstr);
133 #endif
134 }
135
136 static void
137 test_fsconfig_set_binary(const unsigned int cmd, const char *cmd_str)
138 {
139 k_fsconfig(fd, cmd, key, blob, max_blob_size);
140 #ifndef PATH_TRACING
141 printf("fsconfig(%d<%s>, %s, \"%s\", ", fd, fd_path, cmd_str, key);
142 print_quoted_hex(blob, max_blob_size);
143 printf(", %d) = %s\n", max_blob_size, errstr);
144 #endif
145
146 k_fsconfig(fd, cmd, key1, blob1, max_blob_size + 1);
147 #ifndef PATH_TRACING
148 printf("fsconfig(%d<%s>, %s, \"%.*s\"..., ",
149 fd, fd_path, cmd_str, max_string_size, key1);
150 print_quoted_hex(blob1, max_blob_size);
151 printf("..., %d) = %s\n", max_blob_size + 1, errstr);
152 #endif
153
154 k_fsconfig(fd, cmd, key, empty, 0);
155 #ifndef PATH_TRACING
156 printf("fsconfig(%d<%s>, %s, \"%s\", \"\", 0) = %s\n",
157 fd, fd_path, cmd_str, key, errstr);
158 #endif
159
160 k_fsconfig(fd, cmd, key, fname, -100);
161 #ifndef PATH_TRACING
162 printf("fsconfig(%d<%s>, %s, \"%s\", %p, -100) = %s\n",
163 fd, fd_path, cmd_str, key, fname, errstr);
164 #endif
165
166 k_fsconfig(fd, cmd, key, fname, huge_blob_size);
167 #ifndef PATH_TRACING
168 printf("fsconfig(%d<%s>, %s, \"%s\", %p, %d) = %s\n",
169 fd, fd_path, cmd_str, key, fname, huge_blob_size, errstr);
170 #endif
171
172 k_fsconfig(-100, cmd, key, fd_path, sizeof(path_full));
173 #ifndef PATH_TRACING
174 printf("fsconfig(-100, %s, \"%s\", ", cmd_str, key);
175 print_quoted_hex(fd_path, sizeof(path_full));
176 printf(", %d) = %s\n", (int) sizeof(path_full), errstr);
177 #endif
178
179 k_fsconfig(-100, cmd, key, fname, fd);
180 #ifndef PATH_TRACING
181 printf("fsconfig(-100, %s, \"%s\", ", cmd_str, key);
182 print_quoted_hex(fname, fd);
183 printf(", %d) = %s\n", fd, errstr);
184 #endif
185 }
186
187 static void
188 test_fsconfig_set_path(const unsigned int cmd, const char *cmd_str)
189 {
190 char *cwd = get_fd_path(get_dir_fd("."));
191
192 fill_memory_ex(fname, PATH_MAX, '0', 10);
193 k_fsconfig(fd, cmd, key, fname, -100);
194 #ifndef PATH_TRACING
195 printf("fsconfig(%d<%s>, %s, \"%s\", \"%.*s\"..., AT_FDCWD<%s>) = %s\n",
196 fd, fd_path, cmd_str, key, (int) PATH_MAX - 1, fname, cwd,
197 errstr);
198 #endif
199
200 fname[PATH_MAX - 1] = '\0';
201 k_fsconfig(fd, cmd, key, fname, -1);
202 #ifndef PATH_TRACING
203 printf("fsconfig(%d<%s>, %s, \"%s\", \"%s\", -1) = %s\n",
204 fd, fd_path, cmd_str, key, fname, errstr);
205 #endif
206
207 k_fsconfig(-100, cmd, key, empty, fd);
208 printf("fsconfig(-100, %s, \"%s\", \"\", %d<%s>) = %s\n",
209 cmd_str, key, fd, fd_path, errstr);
210
211 k_fsconfig(-1, cmd, 0, fd_path, -100);
212 printf("fsconfig(-1, %s, NULL, \"%s\", AT_FDCWD<%s>) = %s\n",
213 cmd_str, fd_path, cwd, errstr);
214
215 k_fsconfig(-1, cmd, efault, efault + 1, fd);
216 printf("fsconfig(-1, %s, %p, %p, %d<%s>) = %s\n",
217 cmd_str, efault, efault + 1, fd, fd_path, errstr);
218
219 k_fsconfig(-100, cmd, key, fname, -1);
220 #ifndef PATH_TRACING
221 printf("fsconfig(-100, %s, \"%s\", \"%s\", -1) = %s\n",
222 cmd_str, key, fname, errstr);
223 #endif
224 }
225
226 static void
227 test_fsconfig_set_fd(const unsigned int cmd, const char *cmd_str)
228 {
229 k_fsconfig(fd, cmd, key, val, -100);
230 #ifndef PATH_TRACING
231 printf("fsconfig(%d<%s>, %s, \"%s\", %p, -100) = %s\n",
232 fd, fd_path, cmd_str, key, val, errstr);
233 #endif
234
235 k_fsconfig(-100, cmd, key1, 0, fd);
236 printf("fsconfig(-100, %s, \"%.*s\"..., NULL, %d<%s>) = %s\n",
237 cmd_str, max_string_size, key1, fd, fd_path, errstr);
238
239 k_fsconfig(-1, cmd, efault, efault + 1, fd);
240 printf("fsconfig(-1, %s, %p, %p, %d<%s>) = %s\n",
241 cmd_str, efault, efault + 1, fd, fd_path, errstr);
242
243 k_fsconfig(-100, cmd, key, fd_path, -1);
244 #ifndef PATH_TRACING
245 printf("fsconfig(-100, %s, \"%s\", %p, -1) = %s\n",
246 cmd_str, key, fd_path, errstr);
247 #endif
248 }
249
250 int
251 main(void)
252 {
253 skip_if_unavailable("/proc/self/fd/");
254
255 fd_path = tail_memdup(path_full, sizeof(path_full));
256 efault = fd_path + sizeof(path_full);
257 empty = efault - 1;
258 fname = tail_alloc(PATH_MAX);
259 key1 = tail_alloc(max_string_size + 1);
260 key = key1 + 1;
261 val1 = tail_alloc(max_string_size + 1);
262 val = val1 + 1;
263 blob1 = tail_alloc(max_blob_size + 1);
264 blob = blob1 + 1;
265
266 fill_memory_ex(fname, PATH_MAX, '0', 10);
267 fill_memory_ex(key1, max_string_size, 'a', 'z' - 'a' + 1);
268 key1[max_string_size] = '\0';
269 fill_memory_ex(val1, max_string_size, 'A', 'Z' - 'A' + 1);
270 val1[max_string_size] = '\0';
271 fill_memory_ex(blob, max_blob_size, '0', 10);
272 blob[0] = 0;
273 blob1[0] = 0;
274 fd = open(fd_path, O_WRONLY);
275 if (fd < 0)
276 perror_msg_and_fail("open: %s", fd_path);
277
278 test_fsconfig_unknown();
279 test_fsconfig_set_flag(ARG_STR(FSCONFIG_SET_FLAG));
280 test_fsconfig_set_string(ARG_STR(FSCONFIG_SET_STRING));
281 test_fsconfig_set_binary(ARG_STR(FSCONFIG_SET_BINARY));
282 test_fsconfig_set_path(ARG_STR(FSCONFIG_SET_PATH));
283 test_fsconfig_set_path(ARG_STR(FSCONFIG_SET_PATH_EMPTY));
284 test_fsconfig_set_fd(ARG_STR(FSCONFIG_SET_FD));
285 test_fsconfig_cmd(ARG_STR(FSCONFIG_CMD_CREATE));
286 test_fsconfig_cmd(ARG_STR(FSCONFIG_CMD_RECONFIGURE));
287
288 puts("+++ exited with 0 +++");
289 return 0;
290 }