xref: /linux/tools/testing/selftests/landlock/audit_test.c (revision 149367545331dbadb4940540f2a43e726aab046d)
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Landlock tests - Audit
4  *
5  * Copyright © 2024-2025 Microsoft Corporation
6  */
7 
8 #define _GNU_SOURCE
9 #include <errno.h>
10 #include <fcntl.h>
11 #include <limits.h>
12 #include <linux/landlock.h>
13 #include <pthread.h>
14 #include <stdlib.h>
15 #include <sys/mount.h>
16 #include <sys/prctl.h>
17 #include <sys/types.h>
18 #include <sys/wait.h>
19 #include <unistd.h>
20 
21 #include "audit.h"
22 #include "common.h"
23 
24 static int matches_log_signal(struct __test_metadata *const _metadata,
25 			      int audit_fd, const pid_t opid, __u64 *domain_id)
26 {
27 	static const char log_template[] = REGEX_LANDLOCK_PREFIX
28 		" blockers=scope\\.signal opid=%d ocomm=\"audit_test\"$";
29 	char log_match[sizeof(log_template) + 10];
30 	int log_match_len;
31 
32 	log_match_len =
33 		snprintf(log_match, sizeof(log_match), log_template, opid);
34 	if (log_match_len > sizeof(log_match))
35 		return -E2BIG;
36 
37 	return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match,
38 				  domain_id);
39 }
40 
41 FIXTURE(audit)
42 {
43 	struct audit_filter audit_filter;
44 	int audit_fd;
45 };
46 
47 FIXTURE_SETUP(audit)
48 {
49 	disable_caps(_metadata);
50 	set_cap(_metadata, CAP_AUDIT_CONTROL);
51 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
52 	EXPECT_LE(0, self->audit_fd)
53 	{
54 		const char *error_msg;
55 
56 		/* kill "$(auditctl -s | sed -ne 's/^pid \([0-9]\+\)$/\1/p')" */
57 		if (self->audit_fd == -EEXIST)
58 			error_msg = "socket already in use (e.g. auditd)";
59 		else
60 			error_msg = strerror(-self->audit_fd);
61 		TH_LOG("Failed to initialize audit: %s", error_msg);
62 	}
63 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
64 }
65 
66 FIXTURE_TEARDOWN(audit)
67 {
68 	set_cap(_metadata, CAP_AUDIT_CONTROL);
69 	EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter));
70 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
71 }
72 
73 TEST_F(audit, layers)
74 {
75 	const struct landlock_ruleset_attr ruleset_attr = {
76 		.scoped = LANDLOCK_SCOPE_SIGNAL,
77 	};
78 	int status, ruleset_fd, i;
79 	__u64(*domain_stack)[LANDLOCK_MAX_NUM_LAYERS];
80 	__u64 prev_dom = 3;
81 	pid_t child;
82 
83 	domain_stack = mmap(NULL, sizeof(*domain_stack), PROT_READ | PROT_WRITE,
84 			    MAP_SHARED | MAP_ANONYMOUS, -1, 0);
85 	ASSERT_NE(MAP_FAILED, domain_stack);
86 	memset(domain_stack, 0, sizeof(*domain_stack));
87 
88 	ruleset_fd =
89 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
90 	ASSERT_LE(0, ruleset_fd);
91 	EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
92 
93 	child = fork();
94 	ASSERT_LE(0, child);
95 	if (child == 0) {
96 		for (i = 0; i < ARRAY_SIZE(*domain_stack); i++) {
97 			__u64 denial_dom = 1;
98 			__u64 allocated_dom = 2;
99 
100 			EXPECT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
101 
102 			/* Creates a denial to get the domain ID. */
103 			EXPECT_EQ(-1, kill(getppid(), 0));
104 			EXPECT_EQ(EPERM, errno);
105 			EXPECT_EQ(0,
106 				  matches_log_signal(_metadata, self->audit_fd,
107 						     getppid(), &denial_dom));
108 			EXPECT_EQ(0, matches_log_domain_allocated(
109 					     self->audit_fd, getpid(),
110 					     &allocated_dom));
111 			EXPECT_NE(denial_dom, 1);
112 			EXPECT_NE(denial_dom, 0);
113 			EXPECT_EQ(denial_dom, allocated_dom);
114 
115 			/* Checks that the new domain is younger than the previous one. */
116 			EXPECT_GT(allocated_dom, prev_dom);
117 			prev_dom = allocated_dom;
118 			(*domain_stack)[i] = allocated_dom;
119 		}
120 
121 		/* Checks that we reached the maximum number of layers. */
122 		EXPECT_EQ(-1, landlock_restrict_self(ruleset_fd, 0));
123 		EXPECT_EQ(E2BIG, errno);
124 
125 		/* Updates filter rules to match the drop record. */
126 		set_cap(_metadata, CAP_AUDIT_CONTROL);
127 		EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
128 		EXPECT_EQ(0,
129 			  audit_filter_exe(self->audit_fd, &self->audit_filter,
130 					   AUDIT_DEL_RULE));
131 		clear_cap(_metadata, CAP_AUDIT_CONTROL);
132 
133 		_exit(_metadata->exit_code);
134 		return;
135 	}
136 
137 	ASSERT_EQ(child, waitpid(child, &status, 0));
138 	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
139 	    WEXITSTATUS(status) != EXIT_SUCCESS)
140 		_metadata->exit_code = KSFT_FAIL;
141 
142 	/*
143 	 * Purges log from deallocated domains.  Records arrive in LIFO order
144 	 * (innermost domain first) because landlock_put_hierarchy() walks the
145 	 * chain sequentially in a single kworker context.
146 	 */
147 	for (i = ARRAY_SIZE(*domain_stack) - 1; i >= 0; i--) {
148 		__u64 deallocated_dom = 2;
149 
150 		EXPECT_EQ(0, matches_log_domain_deallocated(self->audit_fd, 1,
151 							    (*domain_stack)[i],
152 							    &deallocated_dom));
153 		EXPECT_EQ((*domain_stack)[i], deallocated_dom)
154 		{
155 			TH_LOG("Failed to match domain %llx (#%d)",
156 			       (unsigned long long)(*domain_stack)[i], i);
157 		}
158 	}
159 	EXPECT_EQ(0, munmap(domain_stack, sizeof(*domain_stack)));
160 	EXPECT_EQ(0, close(ruleset_fd));
161 }
162 
163 struct thread_data {
164 	pid_t parent_pid;
165 	int ruleset_fd, pipe_child, pipe_parent;
166 	bool mute_subdomains;
167 };
168 
169 static void *thread_audit_test(void *arg)
170 {
171 	const struct thread_data *data = (struct thread_data *)arg;
172 	uintptr_t err = 0;
173 	char buffer;
174 
175 	/* TGID and TID are different for a second thread. */
176 	if (getpid() == gettid()) {
177 		err = 1;
178 		goto out;
179 	}
180 
181 	if (landlock_restrict_self(data->ruleset_fd, 0)) {
182 		err = 2;
183 		goto out;
184 	}
185 
186 	if (close(data->ruleset_fd)) {
187 		err = 3;
188 		goto out;
189 	}
190 
191 	/* Creates a denial to get the domain ID. */
192 	if (kill(data->parent_pid, 0) != -1) {
193 		err = 4;
194 		goto out;
195 	}
196 
197 	if (EPERM != errno) {
198 		err = 5;
199 		goto out;
200 	}
201 
202 	/* Signals the parent to read denial logs. */
203 	if (write(data->pipe_child, ".", 1) != 1) {
204 		err = 6;
205 		goto out;
206 	}
207 
208 	/* Waits for the parent to update audit filters. */
209 	if (read(data->pipe_parent, &buffer, 1) != 1) {
210 		err = 7;
211 		goto out;
212 	}
213 
214 out:
215 	close(data->pipe_child);
216 	close(data->pipe_parent);
217 	return (void *)err;
218 }
219 
220 /* Checks that the PID tied to a domain is not a TID but the TGID. */
221 TEST_F(audit, thread)
222 {
223 	const struct landlock_ruleset_attr ruleset_attr = {
224 		.scoped = LANDLOCK_SCOPE_SIGNAL,
225 	};
226 	__u64 denial_dom = 1;
227 	__u64 allocated_dom = 2;
228 	__u64 deallocated_dom = 3;
229 	pthread_t thread;
230 	int pipe_child[2], pipe_parent[2];
231 	char buffer;
232 	struct thread_data child_data;
233 
234 	child_data.parent_pid = getppid();
235 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
236 	child_data.pipe_child = pipe_child[1];
237 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
238 	child_data.pipe_parent = pipe_parent[0];
239 	child_data.ruleset_fd =
240 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
241 	ASSERT_LE(0, child_data.ruleset_fd);
242 
243 	/* TGID and TID are the same for the initial thread . */
244 	EXPECT_EQ(getpid(), gettid());
245 	EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
246 	ASSERT_EQ(0, pthread_create(&thread, NULL, thread_audit_test,
247 				    &child_data));
248 
249 	/* Waits for the child to generate a denial. */
250 	ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
251 	EXPECT_EQ(0, close(pipe_child[0]));
252 
253 	/* Matches the signal log to get the domain ID. */
254 	EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
255 					child_data.parent_pid, &denial_dom));
256 	EXPECT_NE(denial_dom, 1);
257 	EXPECT_NE(denial_dom, 0);
258 
259 	EXPECT_EQ(0, matches_log_domain_allocated(self->audit_fd, getpid(),
260 						  &allocated_dom));
261 	EXPECT_EQ(denial_dom, allocated_dom);
262 
263 	/* Updates filter rules to match the drop record. */
264 	set_cap(_metadata, CAP_AUDIT_CONTROL);
265 	EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
266 	EXPECT_EQ(0, audit_filter_exe(self->audit_fd, &self->audit_filter,
267 				      AUDIT_DEL_RULE));
268 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
269 
270 	/* Signals the thread to exit, which will generate a domain deallocation. */
271 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
272 	EXPECT_EQ(0, close(pipe_parent[1]));
273 	ASSERT_EQ(0, pthread_join(thread, NULL));
274 
275 	EXPECT_EQ(0, matches_log_domain_deallocated(
276 			     self->audit_fd, 1, denial_dom, &deallocated_dom));
277 	EXPECT_EQ(denial_dom, deallocated_dom);
278 }
279 
280 /*
281  * Verifies that log_subdomains_off set via the ruleset_fd=-1 path (without
282  * creating a domain) is inherited by children across fork().  This exercises
283  * the hook_cred_transfer() fix: the Landlock credential blob must be copied
284  * even when the source credential has no domain.
285  *
286  * Phase 1 (baseline): a child without muting creates a domain and triggers a
287  * denial that IS logged.
288  *
289  * Phase 2 (after muting): the parent mutes subdomain logs, forks another child
290  * who creates a domain and triggers a denial that is NOT logged.
291  */
292 TEST_F(audit, log_subdomains_off_fork)
293 {
294 	const struct landlock_ruleset_attr ruleset_attr = {
295 		.scoped = LANDLOCK_SCOPE_SIGNAL,
296 	};
297 	struct audit_records records;
298 	int ruleset_fd, status;
299 	pid_t child;
300 
301 	ruleset_fd =
302 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
303 	ASSERT_LE(0, ruleset_fd);
304 
305 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
306 
307 	/*
308 	 * Phase 1: forks a child that creates a domain and triggers a denial
309 	 * before any muting.  This proves the audit path works.
310 	 */
311 	child = fork();
312 	ASSERT_LE(0, child);
313 	if (child == 0) {
314 		ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
315 		ASSERT_EQ(-1, kill(getppid(), 0));
316 		ASSERT_EQ(EPERM, errno);
317 		_exit(0);
318 		return;
319 	}
320 
321 	ASSERT_EQ(child, waitpid(child, &status, 0));
322 	ASSERT_EQ(true, WIFEXITED(status));
323 	ASSERT_EQ(0, WEXITSTATUS(status));
324 
325 	/* The denial must be logged (baseline). */
326 	EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd, getpid(),
327 					NULL));
328 
329 	/* Drains any remaining records (e.g. domain allocation). */
330 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
331 
332 	/*
333 	 * Mutes subdomain logs without creating a domain.  The parent's
334 	 * credential has domain=NULL and log_subdomains_off=1.
335 	 */
336 	ASSERT_EQ(0, landlock_restrict_self(
337 			     -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF));
338 
339 	/*
340 	 * Phase 2: forks a child that creates a domain and triggers a denial.
341 	 * Because log_subdomains_off was inherited via fork(), the child's
342 	 * domain has log_status=LANDLOCK_LOG_DISABLED.
343 	 */
344 	child = fork();
345 	ASSERT_LE(0, child);
346 	if (child == 0) {
347 		ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0));
348 		ASSERT_EQ(-1, kill(getppid(), 0));
349 		ASSERT_EQ(EPERM, errno);
350 		_exit(0);
351 		return;
352 	}
353 
354 	ASSERT_EQ(child, waitpid(child, &status, 0));
355 	ASSERT_EQ(true, WIFEXITED(status));
356 	ASSERT_EQ(0, WEXITSTATUS(status));
357 
358 	/* No denial record should appear. */
359 	EXPECT_EQ(-EAGAIN, matches_log_signal(_metadata, self->audit_fd,
360 					      getpid(), NULL));
361 
362 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
363 	EXPECT_EQ(0, records.access);
364 
365 	EXPECT_EQ(0, close(ruleset_fd));
366 }
367 
368 /*
369  * Thread function: runs two rounds of (create domain, trigger denial, signal
370  * back), waiting for the main thread before each round.  When mute_subdomains
371  * is set, phase 1 also mutes subdomain logs via the fd=-1 path before creating
372  * the domain.  The ruleset_fd is kept open across both rounds so each
373  * restrict_self call stacks a new domain layer.
374  */
375 static void *thread_sandbox_deny_twice(void *arg)
376 {
377 	const struct thread_data *data = (struct thread_data *)arg;
378 	uintptr_t err = 0;
379 	char buffer;
380 
381 	/* Phase 1: optionally mutes, creates a domain, and triggers a denial. */
382 	if (read(data->pipe_parent, &buffer, 1) != 1) {
383 		err = 1;
384 		goto out;
385 	}
386 
387 	if (data->mute_subdomains &&
388 	    landlock_restrict_self(-1,
389 				   LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) {
390 		err = 2;
391 		goto out;
392 	}
393 
394 	if (landlock_restrict_self(data->ruleset_fd, 0)) {
395 		err = 3;
396 		goto out;
397 	}
398 
399 	if (kill(data->parent_pid, 0) != -1 || errno != EPERM) {
400 		err = 4;
401 		goto out;
402 	}
403 
404 	if (write(data->pipe_child, ".", 1) != 1) {
405 		err = 5;
406 		goto out;
407 	}
408 
409 	/* Phase 2: stacks another domain and triggers a denial. */
410 	if (read(data->pipe_parent, &buffer, 1) != 1) {
411 		err = 6;
412 		goto out;
413 	}
414 
415 	if (landlock_restrict_self(data->ruleset_fd, 0)) {
416 		err = 7;
417 		goto out;
418 	}
419 
420 	if (kill(data->parent_pid, 0) != -1 || errno != EPERM) {
421 		err = 8;
422 		goto out;
423 	}
424 
425 	if (write(data->pipe_child, ".", 1) != 1) {
426 		err = 9;
427 		goto out;
428 	}
429 
430 out:
431 	close(data->ruleset_fd);
432 	close(data->pipe_child);
433 	close(data->pipe_parent);
434 	return (void *)err;
435 }
436 
437 /*
438  * Verifies that LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF with
439  * LANDLOCK_RESTRICT_SELF_TSYNC and ruleset_fd=-1 propagates log_subdomains_off
440  * to a sibling thread, suppressing audit logging on domains it subsequently
441  * creates.
442  *
443  * Phase 1 (before TSYNC) acts as an inline baseline: the sibling creates a
444  * domain and triggers a denial that IS logged.
445  *
446  * Phase 2 (after TSYNC) verifies suppression: the sibling stacks another domain
447  * and triggers a denial that is NOT logged.
448  */
449 TEST_F(audit, log_subdomains_off_tsync)
450 {
451 	const struct landlock_ruleset_attr ruleset_attr = {
452 		.scoped = LANDLOCK_SCOPE_SIGNAL,
453 	};
454 	struct audit_records records;
455 	struct thread_data child_data = {};
456 	int pipe_child[2], pipe_parent[2];
457 	char buffer;
458 	pthread_t thread;
459 	void *thread_ret;
460 
461 	child_data.parent_pid = getppid();
462 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
463 	child_data.pipe_child = pipe_child[1];
464 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
465 	child_data.pipe_parent = pipe_parent[0];
466 	child_data.ruleset_fd =
467 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
468 	ASSERT_LE(0, child_data.ruleset_fd);
469 
470 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
471 
472 	/* Creates the sibling thread. */
473 	ASSERT_EQ(0, pthread_create(&thread, NULL, thread_sandbox_deny_twice,
474 				    &child_data));
475 
476 	/*
477 	 * Phase 1: the sibling creates a domain and triggers a denial before
478 	 * any log muting.  This proves the audit path works.
479 	 */
480 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
481 	ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
482 
483 	/* The denial must be logged. */
484 	EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
485 					child_data.parent_pid, NULL));
486 
487 	/* Drains any remaining records (e.g. domain allocation). */
488 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
489 
490 	/*
491 	 * Mutes subdomain logs and propagates to the sibling thread via TSYNC,
492 	 * without creating a domain.
493 	 */
494 	ASSERT_EQ(0, landlock_restrict_self(
495 			     -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF |
496 					 LANDLOCK_RESTRICT_SELF_TSYNC));
497 
498 	/*
499 	 * Phase 2: the sibling stacks another domain and triggers a denial.
500 	 * Because log_subdomains_off was propagated via TSYNC, the new domain
501 	 * has log_status=LANDLOCK_LOG_DISABLED.
502 	 */
503 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
504 	ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
505 
506 	/* No denial record should appear. */
507 	EXPECT_EQ(-EAGAIN, matches_log_signal(_metadata, self->audit_fd,
508 					      child_data.parent_pid, NULL));
509 
510 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
511 	EXPECT_EQ(0, records.access);
512 
513 	EXPECT_EQ(0, close(pipe_child[0]));
514 	EXPECT_EQ(0, close(pipe_parent[1]));
515 	ASSERT_EQ(0, pthread_join(thread, &thread_ret));
516 	EXPECT_EQ(NULL, thread_ret);
517 }
518 
519 /*
520  * Verifies that LANDLOCK_RESTRICT_SELF_TSYNC without
521  * LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF overrides a sibling thread's
522  * log_subdomains_off, re-enabling audit logging on domains the sibling
523  * subsequently creates.
524  *
525  * Phase 1: the sibling sets log_subdomains_off, creates a muted domain, and
526  * triggers a denial that is NOT logged.
527  *
528  * Phase 2 (after TSYNC without LOG_SUBDOMAINS_OFF): the sibling stacks another
529  * domain and triggers a denial that IS logged, proving the muting was
530  * overridden.
531  */
532 TEST_F(audit, tsync_override_log_subdomains_off)
533 {
534 	const struct landlock_ruleset_attr ruleset_attr = {
535 		.scoped = LANDLOCK_SCOPE_SIGNAL,
536 	};
537 	struct audit_records records;
538 	struct thread_data child_data = {};
539 	int pipe_child[2], pipe_parent[2];
540 	char buffer;
541 	pthread_t thread;
542 	void *thread_ret;
543 
544 	child_data.parent_pid = getppid();
545 	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
546 	child_data.pipe_child = pipe_child[1];
547 	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
548 	child_data.pipe_parent = pipe_parent[0];
549 	child_data.ruleset_fd =
550 		landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
551 	ASSERT_LE(0, child_data.ruleset_fd);
552 
553 	ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
554 
555 	child_data.mute_subdomains = true;
556 
557 	/* Creates the sibling thread. */
558 	ASSERT_EQ(0, pthread_create(&thread, NULL, thread_sandbox_deny_twice,
559 				    &child_data));
560 
561 	/*
562 	 * Phase 1: the sibling mutes subdomain logs, creates a domain, and
563 	 * triggers a denial.  The denial must not be logged.
564 	 */
565 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
566 	ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
567 
568 	EXPECT_EQ(-EAGAIN, matches_log_signal(_metadata, self->audit_fd,
569 					      child_data.parent_pid, NULL));
570 
571 	/* Drains any remaining records. */
572 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
573 	EXPECT_EQ(0, records.access);
574 
575 	/*
576 	 * Overrides the sibling's log_subdomains_off by calling TSYNC without
577 	 * LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF.
578 	 */
579 	ASSERT_EQ(0, landlock_restrict_self(child_data.ruleset_fd,
580 					    LANDLOCK_RESTRICT_SELF_TSYNC));
581 
582 	/*
583 	 * Phase 2: the sibling stacks another domain and triggers a denial.
584 	 * Because TSYNC replaced its log_subdomains_off with 0, the new domain
585 	 * has log_status=LANDLOCK_LOG_PENDING.
586 	 */
587 	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
588 	ASSERT_EQ(1, read(pipe_child[0], &buffer, 1));
589 
590 	/* The denial must be logged. */
591 	EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
592 					child_data.parent_pid, NULL));
593 
594 	EXPECT_EQ(0, close(pipe_child[0]));
595 	EXPECT_EQ(0, close(pipe_parent[1]));
596 	ASSERT_EQ(0, pthread_join(thread, &thread_ret));
597 	EXPECT_EQ(NULL, thread_ret);
598 }
599 
600 FIXTURE(audit_flags)
601 {
602 	struct audit_filter audit_filter;
603 	int audit_fd;
604 	__u64 *domain_id;
605 };
606 
607 FIXTURE_VARIANT(audit_flags)
608 {
609 	const int restrict_flags;
610 	const __u64 quiet_scoped;
611 };
612 
613 /* clang-format off */
614 FIXTURE_VARIANT_ADD(audit_flags, default) {
615 	/* clang-format on */
616 	.restrict_flags = 0,
617 	.quiet_scoped = 0,
618 };
619 
620 /* clang-format off */
621 FIXTURE_VARIANT_ADD(audit_flags, same_exec_off) {
622 	/* clang-format on */
623 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
624 	.quiet_scoped = 0,
625 };
626 
627 /* clang-format off */
628 FIXTURE_VARIANT_ADD(audit_flags, subdomains_off) {
629 	/* clang-format on */
630 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
631 	.quiet_scoped = 0,
632 };
633 
634 /* clang-format off */
635 FIXTURE_VARIANT_ADD(audit_flags, cross_exec_on) {
636 	/* clang-format on */
637 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
638 	.quiet_scoped = 0,
639 };
640 
641 /* clang-format off */
642 FIXTURE_VARIANT_ADD(audit_flags, signal_quieted) {
643 	/* clang-format on */
644 	.restrict_flags = 0,
645 	.quiet_scoped = LANDLOCK_SCOPE_SIGNAL,
646 };
647 
648 FIXTURE_SETUP(audit_flags)
649 {
650 	disable_caps(_metadata);
651 	set_cap(_metadata, CAP_AUDIT_CONTROL);
652 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
653 	EXPECT_LE(0, self->audit_fd)
654 	{
655 		const char *error_msg;
656 
657 		/* kill "$(auditctl -s | sed -ne 's/^pid \([0-9]\+\)$/\1/p')" */
658 		if (self->audit_fd == -EEXIST)
659 			error_msg = "socket already in use (e.g. auditd)";
660 		else
661 			error_msg = strerror(-self->audit_fd);
662 		TH_LOG("Failed to initialize audit: %s", error_msg);
663 	}
664 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
665 
666 	self->domain_id = mmap(NULL, sizeof(*self->domain_id),
667 			       PROT_READ | PROT_WRITE,
668 			       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
669 	ASSERT_NE(MAP_FAILED, self->domain_id);
670 	/* Domain IDs are greater or equal to 2^32. */
671 	*self->domain_id = 1;
672 }
673 
674 FIXTURE_TEARDOWN(audit_flags)
675 {
676 	EXPECT_EQ(0, munmap(self->domain_id, sizeof(*self->domain_id)));
677 
678 	set_cap(_metadata, CAP_AUDIT_CONTROL);
679 	EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter));
680 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
681 }
682 
683 TEST_F(audit_flags, signal)
684 {
685 	int status;
686 	pid_t child;
687 	struct audit_records records;
688 	__u64 deallocated_dom = 2;
689 	bool expect_audit = !(variant->restrict_flags &
690 			      LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) &&
691 			    !(variant->quiet_scoped & LANDLOCK_SCOPE_SIGNAL);
692 
693 	child = fork();
694 	ASSERT_LE(0, child);
695 	if (child == 0) {
696 		const struct landlock_ruleset_attr ruleset_attr = {
697 			.scoped = LANDLOCK_SCOPE_SIGNAL,
698 			.quiet_scoped = variant->quiet_scoped,
699 		};
700 		int ruleset_fd;
701 
702 		/* Add filesystem restrictions. */
703 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
704 						     sizeof(ruleset_attr), 0);
705 		ASSERT_LE(0, ruleset_fd);
706 		EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
707 		ASSERT_EQ(0, landlock_restrict_self(ruleset_fd,
708 						    variant->restrict_flags));
709 		EXPECT_EQ(0, close(ruleset_fd));
710 
711 		/* First signal checks to test log entries. */
712 		EXPECT_EQ(-1, kill(getppid(), 0));
713 		EXPECT_EQ(EPERM, errno);
714 
715 		if (!expect_audit) {
716 			EXPECT_EQ(-EAGAIN, matches_log_signal(
717 						   _metadata, self->audit_fd,
718 						   getppid(), self->domain_id));
719 			EXPECT_EQ(*self->domain_id, 1);
720 		} else {
721 			__u64 allocated_dom = 3;
722 
723 			EXPECT_EQ(0, matches_log_signal(
724 					     _metadata, self->audit_fd,
725 					     getppid(), self->domain_id));
726 
727 			/* Checks domain information records. */
728 			EXPECT_EQ(0, matches_log_domain_allocated(
729 					     self->audit_fd, getpid(),
730 					     &allocated_dom));
731 			EXPECT_NE(*self->domain_id, 1);
732 			EXPECT_NE(*self->domain_id, 0);
733 			EXPECT_EQ(*self->domain_id, allocated_dom);
734 		}
735 
736 		/* Second signal checks to test audit_count_records(). */
737 		EXPECT_EQ(-1, kill(getppid(), 0));
738 		EXPECT_EQ(EPERM, errno);
739 
740 		/* Makes sure there is no superfluous logged records. */
741 		EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
742 		if (!expect_audit) {
743 			EXPECT_EQ(0, records.access);
744 		} else {
745 			EXPECT_EQ(1, records.access);
746 		}
747 		EXPECT_EQ(0, records.domain);
748 
749 		/* Updates filter rules to match the drop record. */
750 		set_cap(_metadata, CAP_AUDIT_CONTROL);
751 		EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
752 		EXPECT_EQ(0,
753 			  audit_filter_exe(self->audit_fd, &self->audit_filter,
754 					   AUDIT_DEL_RULE));
755 		clear_cap(_metadata, CAP_AUDIT_CONTROL);
756 
757 		_exit(_metadata->exit_code);
758 		return;
759 	}
760 
761 	ASSERT_EQ(child, waitpid(child, &status, 0));
762 	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
763 	    WEXITSTATUS(status) != EXIT_SUCCESS)
764 		_metadata->exit_code = KSFT_FAIL;
765 
766 	if (!expect_audit) {
767 		/*
768 		 * No deallocation record: denials=0 never matches a real
769 		 * record.
770 		 */
771 		EXPECT_EQ(-EAGAIN,
772 			  matches_log_domain_deallocated(self->audit_fd, 0, 0,
773 							 &deallocated_dom));
774 		EXPECT_EQ(deallocated_dom, 2);
775 	} else {
776 		EXPECT_EQ(0, matches_log_domain_deallocated(self->audit_fd, 2,
777 							    *self->domain_id,
778 							    &deallocated_dom));
779 		EXPECT_NE(deallocated_dom, 2);
780 		EXPECT_NE(deallocated_dom, 0);
781 		EXPECT_EQ(deallocated_dom, *self->domain_id);
782 	}
783 }
784 
785 static int matches_log_fs_read_root(int audit_fd)
786 {
787 	return audit_match_record(
788 		audit_fd, AUDIT_LANDLOCK_ACCESS,
789 		REGEX_LANDLOCK_PREFIX
790 		" blockers=fs\\.read_dir path=\"/\" dev=\"[^\"]\\+\" ino=[0-9]\\+$",
791 		NULL);
792 }
793 
794 FIXTURE(audit_exec)
795 {
796 	struct audit_filter audit_filter;
797 	int audit_fd;
798 };
799 
800 FIXTURE_VARIANT(audit_exec)
801 {
802 	const int restrict_flags;
803 };
804 
805 /* clang-format off */
806 FIXTURE_VARIANT_ADD(audit_exec, default) {
807 	/* clang-format on */
808 	.restrict_flags = 0,
809 };
810 
811 /* clang-format off */
812 FIXTURE_VARIANT_ADD(audit_exec, same_exec_off) {
813 	/* clang-format on */
814 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
815 };
816 
817 /* clang-format off */
818 FIXTURE_VARIANT_ADD(audit_exec, subdomains_off) {
819 	/* clang-format on */
820 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
821 };
822 
823 /* clang-format off */
824 FIXTURE_VARIANT_ADD(audit_exec, cross_exec_on) {
825 	/* clang-format on */
826 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
827 };
828 
829 /* clang-format off */
830 FIXTURE_VARIANT_ADD(audit_exec, subdomains_off_and_cross_exec_on) {
831 	/* clang-format on */
832 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF |
833 			  LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
834 };
835 
836 FIXTURE_SETUP(audit_exec)
837 {
838 	disable_caps(_metadata);
839 	set_cap(_metadata, CAP_AUDIT_CONTROL);
840 
841 	self->audit_fd = audit_init();
842 	EXPECT_LE(0, self->audit_fd)
843 	{
844 		const char *error_msg;
845 
846 		/* kill "$(auditctl -s | sed -ne 's/^pid \([0-9]\+\)$/\1/p')" */
847 		if (self->audit_fd == -EEXIST)
848 			error_msg = "socket already in use (e.g. auditd)";
849 		else
850 			error_msg = strerror(-self->audit_fd);
851 		TH_LOG("Failed to initialize audit: %s", error_msg);
852 	}
853 
854 	/* Applies test filter for the bin_wait_pipe_sandbox program. */
855 	EXPECT_EQ(0, audit_init_filter_exe(&self->audit_filter,
856 					   bin_wait_pipe_sandbox));
857 	EXPECT_EQ(0, audit_filter_exe(self->audit_fd, &self->audit_filter,
858 				      AUDIT_ADD_RULE));
859 
860 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
861 }
862 
863 FIXTURE_TEARDOWN(audit_exec)
864 {
865 	set_cap(_metadata, CAP_AUDIT_CONTROL);
866 	EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter));
867 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
868 }
869 
870 TEST_F(audit_exec, signal_and_open)
871 {
872 	struct audit_records records;
873 	int pipe_child[2], pipe_parent[2];
874 	char buf_parent;
875 	pid_t child;
876 	int status;
877 
878 	ASSERT_EQ(0, pipe2(pipe_child, 0));
879 	ASSERT_EQ(0, pipe2(pipe_parent, 0));
880 
881 	child = fork();
882 	ASSERT_LE(0, child);
883 	if (child == 0) {
884 		const struct landlock_ruleset_attr layer1 = {
885 			.scoped = LANDLOCK_SCOPE_SIGNAL,
886 		};
887 		char pipe_child_str[12], pipe_parent_str[12];
888 		char *const argv[] = { (char *)bin_wait_pipe_sandbox,
889 				       pipe_child_str, pipe_parent_str, NULL };
890 		int ruleset_fd;
891 
892 		/* Passes the pipe FDs to the executed binary. */
893 		EXPECT_EQ(0, close(pipe_child[0]));
894 		EXPECT_EQ(0, close(pipe_parent[1]));
895 		snprintf(pipe_child_str, sizeof(pipe_child_str), "%d",
896 			 pipe_child[1]);
897 		snprintf(pipe_parent_str, sizeof(pipe_parent_str), "%d",
898 			 pipe_parent[0]);
899 
900 		ruleset_fd =
901 			landlock_create_ruleset(&layer1, sizeof(layer1), 0);
902 		if (ruleset_fd < 0) {
903 			perror("Failed to create a ruleset");
904 			_exit(1);
905 		}
906 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
907 		if (landlock_restrict_self(ruleset_fd,
908 					   variant->restrict_flags)) {
909 			perror("Failed to restrict self");
910 			_exit(1);
911 		}
912 		close(ruleset_fd);
913 
914 		ASSERT_EQ(0, execve(argv[0], argv, NULL))
915 		{
916 			TH_LOG("Failed to execute \"%s\": %s", argv[0],
917 			       strerror(errno));
918 		};
919 		_exit(1);
920 		return;
921 	}
922 
923 	EXPECT_EQ(0, close(pipe_child[1]));
924 	EXPECT_EQ(0, close(pipe_parent[0]));
925 
926 	/* Waits for the child. */
927 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
928 
929 	/* Tests that there was no denial until now. */
930 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
931 	EXPECT_EQ(0, records.access);
932 	EXPECT_EQ(0, records.domain);
933 
934 	/*
935 	 * Wait for the child to do a first denied action by layer1 and
936 	 * sandbox itself with layer2.
937 	 */
938 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
939 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
940 
941 	/* Tests that the audit record only matches the child. */
942 	if (variant->restrict_flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON) {
943 		/* Matches the current domain. */
944 		EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
945 						getpid(), NULL));
946 	}
947 
948 	/* Checks that we didn't miss anything. */
949 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
950 	EXPECT_EQ(0, records.access);
951 
952 	/*
953 	 * Wait for the child to do a second denied action by layer1 and
954 	 * layer2, and sandbox itself with layer3.
955 	 */
956 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
957 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
958 
959 	/* Tests that the audit record only matches the child. */
960 	if (variant->restrict_flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON) {
961 		/* Matches the current domain. */
962 		EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
963 						getpid(), NULL));
964 	}
965 
966 	if (!(variant->restrict_flags &
967 	      LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) {
968 		/* Matches the child domain. */
969 		EXPECT_EQ(0, matches_log_fs_read_root(self->audit_fd));
970 	}
971 
972 	/* Checks that we didn't miss anything. */
973 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
974 	EXPECT_EQ(0, records.access);
975 
976 	/* Waits for the child to terminate. */
977 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
978 	ASSERT_EQ(child, waitpid(child, &status, 0));
979 	ASSERT_EQ(1, WIFEXITED(status));
980 	ASSERT_EQ(0, WEXITSTATUS(status));
981 
982 	/* Tests that the audit record only matches the child. */
983 	if (!(variant->restrict_flags &
984 	      LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) {
985 		/*
986 		 * Matches the child domains, which tests that the
987 		 * llcred->domain_exec bitmask is correctly updated with a new
988 		 * domain.
989 		 */
990 		EXPECT_EQ(0, matches_log_fs_read_root(self->audit_fd));
991 		EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
992 						getpid(), NULL));
993 	}
994 
995 	/* Checks that we didn't miss anything. */
996 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
997 	EXPECT_EQ(0, records.access);
998 }
999 
1000 TEST_HARNESS_MAIN
1001