projects/linux·blob master · refs

739 lines · 21.1 KiB

1// SPDX-License-Identifier: GPL-2.0
2/*
3 * Landlock tests - Common user space base
4 *
5 * Copyright © 2017-2020 Mickaël Salaün <[email protected]>
6 * Copyright © 2019-2020 ANSSI
7 */
8
9#define _GNU_SOURCE
10#include <errno.h>
11#include <fcntl.h>
12#include <linux/keyctl.h>
13#include <linux/landlock.h>
14#include <string.h>
15#include <sys/prctl.h>
16#include <sys/socket.h>
17#include <sys/types.h>
18
19#include "common.h"
20
21#ifndef O_PATH
22#define O_PATH 010000000
23#endif
24
25TEST(inconsistent_attr)
26{
27 const long page_size = sysconf(_SC_PAGESIZE);
28 char *const buf = malloc(page_size + 1);
29 struct landlock_ruleset_attr *const ruleset_attr = (void *)buf;
30
31 ASSERT_NE(NULL, buf);
32
33 /* Checks copy_from_user(). */
34 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 0, 0));
35 /* The size if less than sizeof(struct landlock_attr_enforce). */
36 ASSERT_EQ(EINVAL, errno);
37 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 1, 0));
38 ASSERT_EQ(EINVAL, errno);
39 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 7, 0));
40 ASSERT_EQ(EINVAL, errno);
41
42 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 1, 0));
43 /* The size if less than sizeof(struct landlock_attr_enforce). */
44 ASSERT_EQ(EFAULT, errno);
45
46 ASSERT_EQ(-1, landlock_create_ruleset(
47 NULL, sizeof(struct landlock_ruleset_attr), 0));
48 ASSERT_EQ(EFAULT, errno);
49
50 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0));
51 ASSERT_EQ(E2BIG, errno);
52
53 /* Checks minimal valid attribute size. */
54 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 8, 0));
55 ASSERT_EQ(ENOMSG, errno);
56 ASSERT_EQ(-1, landlock_create_ruleset(
57 ruleset_attr,
58 sizeof(struct landlock_ruleset_attr), 0));
59 ASSERT_EQ(ENOMSG, errno);
60 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size, 0));
61 ASSERT_EQ(ENOMSG, errno);
62
63 /* Checks non-zero value. */
64 buf[page_size - 2] = '.';
65 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size, 0));
66 ASSERT_EQ(E2BIG, errno);
67
68 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0));
69 ASSERT_EQ(E2BIG, errno);
70
71 free(buf);
72}
73
74TEST(abi_version)
75{
76 const struct landlock_ruleset_attr ruleset_attr = {
77 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
78 };
79 ASSERT_EQ(11, landlock_create_ruleset(NULL, 0,
80 LANDLOCK_CREATE_RULESET_VERSION));
81
82 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,
83 LANDLOCK_CREATE_RULESET_VERSION));
84 ASSERT_EQ(EINVAL, errno);
85
86 ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr),
87 LANDLOCK_CREATE_RULESET_VERSION));
88 ASSERT_EQ(EINVAL, errno);
89
90 ASSERT_EQ(-1,
91 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr),
92 LANDLOCK_CREATE_RULESET_VERSION));
93 ASSERT_EQ(EINVAL, errno);
94
95 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0,
96 LANDLOCK_CREATE_RULESET_VERSION |
97 1 << 31));
98 ASSERT_EQ(EINVAL, errno);
99}
100
101/*
102 * Old source trees might not have the set of Kselftest fixes related to kernel
103 * UAPI headers.
104 */
105#ifndef LANDLOCK_CREATE_RULESET_ERRATA
106#define LANDLOCK_CREATE_RULESET_ERRATA (1U << 1)
107#endif
108
109TEST(errata)
110{
111 const struct landlock_ruleset_attr ruleset_attr = {
112 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
113 };
114 int errata;
115
116 errata = landlock_create_ruleset(NULL, 0,
117 LANDLOCK_CREATE_RULESET_ERRATA);
118 /* The errata bitmask will not be backported to tests. */
119 ASSERT_LE(0, errata);
120 TH_LOG("errata: 0x%x", errata);
121
122 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,
123 LANDLOCK_CREATE_RULESET_ERRATA));
124 ASSERT_EQ(EINVAL, errno);
125
126 ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr),
127 LANDLOCK_CREATE_RULESET_ERRATA));
128 ASSERT_EQ(EINVAL, errno);
129
130 ASSERT_EQ(-1,
131 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr),
132 LANDLOCK_CREATE_RULESET_ERRATA));
133 ASSERT_EQ(EINVAL, errno);
134
135 ASSERT_EQ(-1, landlock_create_ruleset(
136 NULL, 0,
137 LANDLOCK_CREATE_RULESET_VERSION |
138 LANDLOCK_CREATE_RULESET_ERRATA));
139 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0,
140 LANDLOCK_CREATE_RULESET_ERRATA |
141 1 << 31));
142 ASSERT_EQ(EINVAL, errno);
143}
144
145/* Tests ordering of syscall argument checks. */
146TEST(create_ruleset_checks_ordering)
147{
148 const int last_flag = LANDLOCK_CREATE_RULESET_ERRATA;
149 const int invalid_flag = last_flag << 1;
150 int ruleset_fd;
151 const struct landlock_ruleset_attr ruleset_attr = {
152 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
153 };
154
155 /* Checks priority for invalid flags. */
156 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, invalid_flag));
157 ASSERT_EQ(EINVAL, errno);
158
159 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, invalid_flag));
160 ASSERT_EQ(EINVAL, errno);
161
162 ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr),
163 invalid_flag));
164 ASSERT_EQ(EINVAL, errno);
165
166 ASSERT_EQ(-1,
167 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr),
168 invalid_flag));
169 ASSERT_EQ(EINVAL, errno);
170
171 /* Checks too big ruleset_attr size. */
172 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, -1, 0));
173 ASSERT_EQ(E2BIG, errno);
174
175 /* Checks too small ruleset_attr size. */
176 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, 0));
177 ASSERT_EQ(EINVAL, errno);
178 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 1, 0));
179 ASSERT_EQ(EINVAL, errno);
180
181 /* Checks valid call. */
182 ruleset_fd =
183 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
184 ASSERT_LE(0, ruleset_fd);
185 ASSERT_EQ(0, close(ruleset_fd));
186}
187
188/* Tests ordering of syscall argument checks. */
189TEST(add_rule_checks_ordering)
190{
191 const struct landlock_ruleset_attr ruleset_attr = {
192 .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
193 };
194 struct landlock_path_beneath_attr path_beneath_attr = {
195 .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
196 .parent_fd = -1,
197 };
198 const int ruleset_fd =
199 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
200
201 ASSERT_LE(0, ruleset_fd);
202
203 /* Checks invalid flags. */
204 ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 100));
205 ASSERT_EQ(EINVAL, errno);
206
207 /* Checks invalid ruleset FD. */
208 ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 0));
209 ASSERT_EQ(EBADF, errno);
210
211 /* Checks invalid rule type. */
212 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, 0, NULL, 0));
213 ASSERT_EQ(EINVAL, errno);
214
215 /* Checks invalid rule attr. */
216 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
217 NULL, 0));
218 ASSERT_EQ(EFAULT, errno);
219
220 /* Checks invalid path_beneath.parent_fd. */
221 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
222 &path_beneath_attr, 0));
223 ASSERT_EQ(EBADF, errno);
224
225 /* Checks valid call. */
226 path_beneath_attr.parent_fd =
227 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
228 ASSERT_LE(0, path_beneath_attr.parent_fd);
229 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
230 &path_beneath_attr, 0));
231 ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
232 ASSERT_EQ(0, close(ruleset_fd));
233}
234
235/* Tests ordering of syscall argument and permission checks. */
236TEST(restrict_self_checks_ordering)
237{
238 const struct landlock_ruleset_attr ruleset_attr = {
239 .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
240 };
241 struct landlock_path_beneath_attr path_beneath_attr = {
242 .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
243 .parent_fd = -1,
244 };
245 const int ruleset_fd =
246 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
247
248 ASSERT_LE(0, ruleset_fd);
249 path_beneath_attr.parent_fd =
250 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
251 ASSERT_LE(0, path_beneath_attr.parent_fd);
252 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
253 &path_beneath_attr, 0));
254 ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
255
256 /* Checks unprivileged enforcement without no_new_privs. */
257 drop_caps(_metadata);
258 /*
259 * The flags validity is checked before the no_new_privs /
260 * CAP_SYS_ADMIN requirement.
261 */
262 ASSERT_EQ(-1, landlock_restrict_self(-1, -1));
263 ASSERT_EQ(EINVAL, errno);
264 ASSERT_EQ(-1, landlock_restrict_self(-1, 0));
265 ASSERT_EQ(EPERM, errno);
266 ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
267 ASSERT_EQ(EPERM, errno);
268 /*
269 * LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS fulfills the no_new_privs /
270 * CAP_SYS_ADMIN requirement but requires a ruleset, so the FD is
271 * checked next.
272 */
273 ASSERT_EQ(-1, landlock_restrict_self(
274 -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
275 ASSERT_EQ(EBADF, errno);
276
277 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
278
279 /* Checks invalid flags. */
280 ASSERT_EQ(-1, landlock_restrict_self(-1, -1));
281 ASSERT_EQ(EINVAL, errno);
282
283 /* Checks invalid ruleset FD. */
284 ASSERT_EQ(-1, landlock_restrict_self(-1, 0));
285 ASSERT_EQ(EBADF, errno);
286
287 /* Checks valid call. */
288 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
289 ASSERT_EQ(0, close(ruleset_fd));
290}
291
292TEST(restrict_self_max_layers)
293{
294 const struct landlock_ruleset_attr ruleset_attr = {
295 .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE,
296 };
297 struct landlock_path_beneath_attr path_beneath_attr = {
298 .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE,
299 .parent_fd = -1,
300 };
301 const int ruleset_fd =
302 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
303 ASSERT_LE(0, ruleset_fd);
304
305 path_beneath_attr.parent_fd =
306 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
307 ASSERT_LE(0, path_beneath_attr.parent_fd);
308 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
309 &path_beneath_attr, 0));
310 ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
311
312 /* Enforces the maximum number of allowed layers. */
313 for (int i = 0; i < LANDLOCK_MAX_NUM_LAYERS; i++)
314 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
315
316 /* Enforces one too many rulesets. */
317 drop_caps(_metadata);
318 ASSERT_EQ(-1, landlock_restrict_self(
319 ruleset_fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
320 ASSERT_EQ(E2BIG, errno);
321
322 /* Checks that the failed call did not set no_new_privs. */
323 ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0));
324 ASSERT_EQ(0, close(ruleset_fd));
325}
326
327TEST(restrict_self_fd)
328{
329 int fd;
330
331 fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
332 ASSERT_LE(0, fd);
333
334 EXPECT_EQ(-1, landlock_restrict_self(fd, 0));
335 EXPECT_EQ(EBADFD, errno);
336}
337
338TEST(restrict_self_fd_flags)
339{
340 int fd;
341
342 fd = open("/dev/null", O_RDONLY | O_CLOEXEC);
343 ASSERT_LE(0, fd);
344
345 /*
346 * LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF accepts -1 but not any file
347 * descriptor.
348 */
349 EXPECT_EQ(-1, landlock_restrict_self(
350 fd, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF));
351 EXPECT_EQ(EBADFD, errno);
352
353 /* LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS requires a ruleset FD. */
354 EXPECT_EQ(-1, landlock_restrict_self(
355 fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
356 EXPECT_EQ(EBADFD, errno);
357}
358
359TEST(restrict_self_flags)
360{
361 const __u32 last_flag = LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS;
362
363 /* Tests invalid flag combinations. */
364
365 EXPECT_EQ(-1, landlock_restrict_self(-1, last_flag << 1));
366 EXPECT_EQ(EINVAL, errno);
367
368 EXPECT_EQ(-1, landlock_restrict_self(-1, -1));
369 EXPECT_EQ(EINVAL, errno);
370
371 /* Tests valid flag combinations. */
372
373 EXPECT_EQ(-1, landlock_restrict_self(-1, 0));
374 EXPECT_EQ(EBADF, errno);
375
376 EXPECT_EQ(-1, landlock_restrict_self(
377 -1, LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF));
378 EXPECT_EQ(EBADF, errno);
379
380 EXPECT_EQ(-1,
381 landlock_restrict_self(
382 -1,
383 LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
384 LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF));
385 EXPECT_EQ(EBADF, errno);
386
387 EXPECT_EQ(-1,
388 landlock_restrict_self(
389 -1,
390 LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON |
391 LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF));
392 EXPECT_EQ(EBADF, errno);
393
394 EXPECT_EQ(-1, landlock_restrict_self(
395 -1, LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON));
396 EXPECT_EQ(EBADF, errno);
397
398 EXPECT_EQ(-1,
399 landlock_restrict_self(
400 -1, LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF |
401 LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON));
402 EXPECT_EQ(EBADF, errno);
403
404 /* LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS requires a ruleset FD. */
405
406 EXPECT_EQ(-1, landlock_restrict_self(
407 -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
408 EXPECT_EQ(EBADF, errno);
409
410 EXPECT_EQ(-1, landlock_restrict_self(
411 -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF |
412 LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
413 EXPECT_EQ(EBADF, errno);
414
415 /* Tests with an invalid ruleset_fd. */
416
417 EXPECT_EQ(-1, landlock_restrict_self(
418 -2, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF));
419 EXPECT_EQ(EBADF, errno);
420
421 EXPECT_EQ(0, landlock_restrict_self(
422 -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF));
423}
424
425TEST(restrict_self_no_new_privs)
426{
427 const struct landlock_ruleset_attr ruleset_attr = {
428 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
429 };
430 const int ruleset_fd =
431 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
432
433 ASSERT_LE(0, ruleset_fd);
434
435 /*
436 * The calling thread does not need CAP_SYS_ADMIN nor an explicit
437 * prctl(2) PR_SET_NO_NEW_PRIVS call.
438 */
439 drop_caps(_metadata);
440 ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0));
441
442 /* Checks that a failed call does not set no_new_privs. */
443 EXPECT_EQ(-1, landlock_restrict_self(
444 -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
445 EXPECT_EQ(EBADF, errno);
446 EXPECT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0));
447
448 /* Checks that a successful call sets no_new_privs. */
449 ASSERT_EQ(0, landlock_restrict_self(
450 ruleset_fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS));
451 EXPECT_EQ(1, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0));
452
453 EXPECT_EQ(0, close(ruleset_fd));
454}
455
456TEST(ruleset_fd_io)
457{
458 struct landlock_ruleset_attr ruleset_attr = {
459 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE,
460 };
461 int ruleset_fd;
462 char buf;
463
464 drop_caps(_metadata);
465 ruleset_fd =
466 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
467 ASSERT_LE(0, ruleset_fd);
468
469 ASSERT_EQ(-1, write(ruleset_fd, ".", 1));
470 ASSERT_EQ(EINVAL, errno);
471 ASSERT_EQ(-1, read(ruleset_fd, &buf, 1));
472 ASSERT_EQ(EINVAL, errno);
473
474 ASSERT_EQ(0, close(ruleset_fd));
475}
476
477/* Tests enforcement of a ruleset FD transferred through a UNIX socket. */
478TEST(ruleset_fd_transfer)
479{
480 struct landlock_ruleset_attr ruleset_attr = {
481 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
482 };
483 struct landlock_path_beneath_attr path_beneath_attr = {
484 .allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
485 };
486 int ruleset_fd_tx, dir_fd;
487 int socket_fds[2];
488 pid_t child;
489 int status;
490
491 drop_caps(_metadata);
492
493 /* Creates a test ruleset with a simple rule. */
494 ruleset_fd_tx =
495 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
496 ASSERT_LE(0, ruleset_fd_tx);
497 path_beneath_attr.parent_fd =
498 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC);
499 ASSERT_LE(0, path_beneath_attr.parent_fd);
500 ASSERT_EQ(0,
501 landlock_add_rule(ruleset_fd_tx, LANDLOCK_RULE_PATH_BENEATH,
502 &path_beneath_attr, 0));
503 ASSERT_EQ(0, close(path_beneath_attr.parent_fd));
504
505 /* Sends the ruleset FD over a socketpair and then close it. */
506 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0,
507 socket_fds));
508 ASSERT_EQ(0, send_fd(socket_fds[0], ruleset_fd_tx));
509 ASSERT_EQ(0, close(socket_fds[0]));
510 ASSERT_EQ(0, close(ruleset_fd_tx));
511
512 child = fork();
513 ASSERT_LE(0, child);
514 if (child == 0) {
515 const int ruleset_fd_rx = recv_fd(socket_fds[1]);
516
517 ASSERT_LE(0, ruleset_fd_rx);
518 ASSERT_EQ(0, close(socket_fds[1]));
519
520 /* Enforces the received ruleset on the child. */
521 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
522 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd_rx, 0));
523 ASSERT_EQ(0, close(ruleset_fd_rx));
524
525 /* Checks that the ruleset enforcement. */
526 ASSERT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
527 ASSERT_EQ(EACCES, errno);
528 dir_fd = open("/tmp", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
529 ASSERT_LE(0, dir_fd);
530 ASSERT_EQ(0, close(dir_fd));
531 _exit(_metadata->exit_code);
532 return;
533 }
534
535 ASSERT_EQ(0, close(socket_fds[1]));
536
537 /* Checks that the parent is unrestricted. */
538 dir_fd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
539 ASSERT_LE(0, dir_fd);
540 ASSERT_EQ(0, close(dir_fd));
541 dir_fd = open("/tmp", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
542 ASSERT_LE(0, dir_fd);
543 ASSERT_EQ(0, close(dir_fd));
544
545 ASSERT_EQ(child, waitpid(child, &status, 0));
546 ASSERT_EQ(1, WIFEXITED(status));
547 ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
548}
549
550TEST(cred_transfer)
551{
552 struct landlock_ruleset_attr ruleset_attr = {
553 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
554 };
555 int ruleset_fd, dir_fd;
556 pid_t child;
557 int status;
558
559 drop_caps(_metadata);
560
561 dir_fd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC);
562 EXPECT_LE(0, dir_fd);
563 EXPECT_EQ(0, close(dir_fd));
564
565 /* Denies opening directories. */
566 ruleset_fd =
567 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
568 ASSERT_LE(0, ruleset_fd);
569 EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
570 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
571 EXPECT_EQ(0, close(ruleset_fd));
572
573 /* Checks ruleset enforcement. */
574 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
575 EXPECT_EQ(EACCES, errno);
576
577 /* Needed for KEYCTL_SESSION_TO_PARENT permission checks */
578 EXPECT_NE(-1, syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, NULL, 0,
579 0, 0))
580 {
581 TH_LOG("Failed to join session keyring: %s", strerror(errno));
582 }
583
584 child = fork();
585 ASSERT_LE(0, child);
586 if (child == 0) {
587 /* Checks ruleset enforcement. */
588 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
589 EXPECT_EQ(EACCES, errno);
590
591 /*
592 * KEYCTL_SESSION_TO_PARENT is a no-op unless we have a
593 * different session keyring in the child, so make that happen.
594 */
595 EXPECT_NE(-1, syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING,
596 NULL, 0, 0, 0));
597
598 /*
599 * KEYCTL_SESSION_TO_PARENT installs credentials on the parent
600 * that never go through the cred_prepare hook, this path uses
601 * cred_transfer instead.
602 */
603 EXPECT_EQ(0, syscall(__NR_keyctl, KEYCTL_SESSION_TO_PARENT, 0,
604 0, 0, 0));
605
606 /* Re-checks ruleset enforcement. */
607 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
608 EXPECT_EQ(EACCES, errno);
609
610 _exit(_metadata->exit_code);
611 return;
612 }
613
614 EXPECT_EQ(child, waitpid(child, &status, 0));
615 EXPECT_EQ(1, WIFEXITED(status));
616 EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status));
617
618 /* Re-checks ruleset enforcement. */
619 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
620 EXPECT_EQ(EACCES, errno);
621}
622
623TEST(useless_quiet_rule_fs)
624{
625 struct landlock_ruleset_attr ruleset_attr = {
626 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
627 .quiet_access_fs = 0,
628 };
629 struct landlock_path_beneath_attr path_beneath_attr = {
630 .allowed_access = LANDLOCK_ACCESS_FS_READ_DIR,
631 };
632 int ruleset_fd, root_fd;
633
634 drop_caps(_metadata);
635 ruleset_fd =
636 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
637 ASSERT_LE(0, ruleset_fd);
638
639 root_fd = open("/", O_PATH | O_CLOEXEC);
640 ASSERT_LE(0, root_fd);
641 path_beneath_attr.parent_fd = root_fd;
642 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH,
643 &path_beneath_attr,
644 LANDLOCK_ADD_RULE_QUIET));
645 ASSERT_EQ(EINVAL, errno);
646
647 /* Check that the rule had not been added. */
648 ASSERT_EQ(0, close(root_fd));
649 enforce_ruleset(_metadata, ruleset_fd);
650 ASSERT_EQ(0, close(ruleset_fd));
651
652 ASSERT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC));
653 ASSERT_EQ(EACCES, errno);
654}
655
656TEST(useless_quiet_rule_net)
657{
658 struct landlock_ruleset_attr ruleset_attr = {
659 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
660 .quiet_access_net = 0,
661 };
662 struct landlock_net_port_attr net_port_attr = {
663 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP,
664 .port = 1024,
665 };
666 int ruleset_fd;
667
668 drop_caps(_metadata);
669 ruleset_fd =
670 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
671 ASSERT_LE(0, ruleset_fd);
672
673 ASSERT_EQ(-1,
674 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT,
675 &net_port_attr, LANDLOCK_ADD_RULE_QUIET));
676 ASSERT_EQ(EINVAL, errno);
677
678 ASSERT_EQ(0, close(ruleset_fd));
679}
680
681TEST(invalid_quiet_bits_1)
682{
683 const struct landlock_ruleset_attr ruleset_attr_fs = {
684 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
685 .quiet_access_fs = LANDLOCK_ACCESS_FS_WRITE_FILE,
686 };
687 const struct landlock_ruleset_attr ruleset_attr_net = {
688 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
689 .quiet_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP,
690 };
691 const struct landlock_ruleset_attr ruleset_attr_scoped = {
692 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
693 .quiet_scoped = LANDLOCK_SCOPE_SIGNAL,
694 };
695
696 /* Quiet bit set but not part of the handled mask. */
697 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_fs,
698 sizeof(ruleset_attr_fs), 0));
699 ASSERT_EQ(EINVAL, errno);
700
701 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_net,
702 sizeof(ruleset_attr_net), 0));
703 ASSERT_EQ(EINVAL, errno);
704
705 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_scoped,
706 sizeof(ruleset_attr_scoped), 0));
707 ASSERT_EQ(EINVAL, errno);
708}
709
710TEST(invalid_quiet_bits_2)
711{
712 const struct landlock_ruleset_attr ruleset_attr_fs = {
713 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR,
714 .quiet_access_fs = 1ULL << 63,
715 };
716 const struct landlock_ruleset_attr ruleset_attr_net = {
717 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP,
718 .quiet_access_net = 1ULL << 63,
719 };
720 const struct landlock_ruleset_attr ruleset_attr_scoped = {
721 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
722 .quiet_scoped = 1ULL << 63,
723 };
724
725 /* Quiet bit outside of the valid access range. */
726 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_fs,
727 sizeof(ruleset_attr_fs), 0));
728 ASSERT_EQ(EINVAL, errno);
729
730 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_net,
731 sizeof(ruleset_attr_net), 0));
732 ASSERT_EQ(EINVAL, errno);
733
734 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_scoped,
735 sizeof(ruleset_attr_scoped), 0));
736 ASSERT_EQ(EINVAL, errno);
737}
738
739TEST_HARNESS_MAIN