xref: /linux/tools/testing/selftests/landlock/audit_test.c (revision 6fa6b5cb60490db2591bb93872b95f72315e5f53)
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)[16];
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 };
611 
612 /* clang-format off */
613 FIXTURE_VARIANT_ADD(audit_flags, default) {
614 	/* clang-format on */
615 	.restrict_flags = 0,
616 };
617 
618 /* clang-format off */
619 FIXTURE_VARIANT_ADD(audit_flags, same_exec_off) {
620 	/* clang-format on */
621 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
622 };
623 
624 /* clang-format off */
625 FIXTURE_VARIANT_ADD(audit_flags, subdomains_off) {
626 	/* clang-format on */
627 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
628 };
629 
630 /* clang-format off */
631 FIXTURE_VARIANT_ADD(audit_flags, cross_exec_on) {
632 	/* clang-format on */
633 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
634 };
635 
636 FIXTURE_SETUP(audit_flags)
637 {
638 	disable_caps(_metadata);
639 	set_cap(_metadata, CAP_AUDIT_CONTROL);
640 	self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
641 	EXPECT_LE(0, self->audit_fd)
642 	{
643 		const char *error_msg;
644 
645 		/* kill "$(auditctl -s | sed -ne 's/^pid \([0-9]\+\)$/\1/p')" */
646 		if (self->audit_fd == -EEXIST)
647 			error_msg = "socket already in use (e.g. auditd)";
648 		else
649 			error_msg = strerror(-self->audit_fd);
650 		TH_LOG("Failed to initialize audit: %s", error_msg);
651 	}
652 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
653 
654 	self->domain_id = mmap(NULL, sizeof(*self->domain_id),
655 			       PROT_READ | PROT_WRITE,
656 			       MAP_SHARED | MAP_ANONYMOUS, -1, 0);
657 	ASSERT_NE(MAP_FAILED, self->domain_id);
658 	/* Domain IDs are greater or equal to 2^32. */
659 	*self->domain_id = 1;
660 }
661 
662 FIXTURE_TEARDOWN(audit_flags)
663 {
664 	EXPECT_EQ(0, munmap(self->domain_id, sizeof(*self->domain_id)));
665 
666 	set_cap(_metadata, CAP_AUDIT_CONTROL);
667 	EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter));
668 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
669 }
670 
671 TEST_F(audit_flags, signal)
672 {
673 	int status;
674 	pid_t child;
675 	struct audit_records records;
676 	__u64 deallocated_dom = 2;
677 
678 	child = fork();
679 	ASSERT_LE(0, child);
680 	if (child == 0) {
681 		const struct landlock_ruleset_attr ruleset_attr = {
682 			.scoped = LANDLOCK_SCOPE_SIGNAL,
683 		};
684 		int ruleset_fd;
685 
686 		/* Add filesystem restrictions. */
687 		ruleset_fd = landlock_create_ruleset(&ruleset_attr,
688 						     sizeof(ruleset_attr), 0);
689 		ASSERT_LE(0, ruleset_fd);
690 		EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0));
691 		ASSERT_EQ(0, landlock_restrict_self(ruleset_fd,
692 						    variant->restrict_flags));
693 		EXPECT_EQ(0, close(ruleset_fd));
694 
695 		/* First signal checks to test log entries. */
696 		EXPECT_EQ(-1, kill(getppid(), 0));
697 		EXPECT_EQ(EPERM, errno);
698 
699 		if (variant->restrict_flags &
700 		    LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
701 			EXPECT_EQ(-EAGAIN, matches_log_signal(
702 						   _metadata, self->audit_fd,
703 						   getppid(), self->domain_id));
704 			EXPECT_EQ(*self->domain_id, 1);
705 		} else {
706 			__u64 allocated_dom = 3;
707 
708 			EXPECT_EQ(0, matches_log_signal(
709 					     _metadata, self->audit_fd,
710 					     getppid(), self->domain_id));
711 
712 			/* Checks domain information records. */
713 			EXPECT_EQ(0, matches_log_domain_allocated(
714 					     self->audit_fd, getpid(),
715 					     &allocated_dom));
716 			EXPECT_NE(*self->domain_id, 1);
717 			EXPECT_NE(*self->domain_id, 0);
718 			EXPECT_EQ(*self->domain_id, allocated_dom);
719 		}
720 
721 		/* Second signal checks to test audit_count_records(). */
722 		EXPECT_EQ(-1, kill(getppid(), 0));
723 		EXPECT_EQ(EPERM, errno);
724 
725 		/* Makes sure there is no superfluous logged records. */
726 		EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
727 		if (variant->restrict_flags &
728 		    LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
729 			EXPECT_EQ(0, records.access);
730 		} else {
731 			EXPECT_EQ(1, records.access);
732 		}
733 
734 		/* Updates filter rules to match the drop record. */
735 		set_cap(_metadata, CAP_AUDIT_CONTROL);
736 		EXPECT_EQ(0, audit_filter_drop(self->audit_fd, AUDIT_ADD_RULE));
737 		EXPECT_EQ(0,
738 			  audit_filter_exe(self->audit_fd, &self->audit_filter,
739 					   AUDIT_DEL_RULE));
740 		clear_cap(_metadata, CAP_AUDIT_CONTROL);
741 
742 		_exit(_metadata->exit_code);
743 		return;
744 	}
745 
746 	ASSERT_EQ(child, waitpid(child, &status, 0));
747 	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
748 	    WEXITSTATUS(status) != EXIT_SUCCESS)
749 		_metadata->exit_code = KSFT_FAIL;
750 
751 	if (variant->restrict_flags &
752 	    LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
753 		/*
754 		 * No deallocation record: denials=0 never matches a real
755 		 * record.
756 		 */
757 		EXPECT_EQ(-EAGAIN,
758 			  matches_log_domain_deallocated(self->audit_fd, 0, 0,
759 							 &deallocated_dom));
760 		EXPECT_EQ(deallocated_dom, 2);
761 	} else {
762 		EXPECT_EQ(0, matches_log_domain_deallocated(self->audit_fd, 2,
763 							    *self->domain_id,
764 							    &deallocated_dom));
765 		EXPECT_NE(deallocated_dom, 2);
766 		EXPECT_NE(deallocated_dom, 0);
767 		EXPECT_EQ(deallocated_dom, *self->domain_id);
768 	}
769 }
770 
771 static int matches_log_fs_read_root(int audit_fd)
772 {
773 	return audit_match_record(
774 		audit_fd, AUDIT_LANDLOCK_ACCESS,
775 		REGEX_LANDLOCK_PREFIX
776 		" blockers=fs\\.read_dir path=\"/\" dev=\"[^\"]\\+\" ino=[0-9]\\+$",
777 		NULL);
778 }
779 
780 FIXTURE(audit_exec)
781 {
782 	struct audit_filter audit_filter;
783 	int audit_fd;
784 };
785 
786 FIXTURE_VARIANT(audit_exec)
787 {
788 	const int restrict_flags;
789 };
790 
791 /* clang-format off */
792 FIXTURE_VARIANT_ADD(audit_exec, default) {
793 	/* clang-format on */
794 	.restrict_flags = 0,
795 };
796 
797 /* clang-format off */
798 FIXTURE_VARIANT_ADD(audit_exec, same_exec_off) {
799 	/* clang-format on */
800 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
801 };
802 
803 /* clang-format off */
804 FIXTURE_VARIANT_ADD(audit_exec, subdomains_off) {
805 	/* clang-format on */
806 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
807 };
808 
809 /* clang-format off */
810 FIXTURE_VARIANT_ADD(audit_exec, cross_exec_on) {
811 	/* clang-format on */
812 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
813 };
814 
815 /* clang-format off */
816 FIXTURE_VARIANT_ADD(audit_exec, subdomains_off_and_cross_exec_on) {
817 	/* clang-format on */
818 	.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF |
819 			  LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
820 };
821 
822 FIXTURE_SETUP(audit_exec)
823 {
824 	disable_caps(_metadata);
825 	set_cap(_metadata, CAP_AUDIT_CONTROL);
826 
827 	self->audit_fd = audit_init();
828 	EXPECT_LE(0, self->audit_fd)
829 	{
830 		const char *error_msg;
831 
832 		/* kill "$(auditctl -s | sed -ne 's/^pid \([0-9]\+\)$/\1/p')" */
833 		if (self->audit_fd == -EEXIST)
834 			error_msg = "socket already in use (e.g. auditd)";
835 		else
836 			error_msg = strerror(-self->audit_fd);
837 		TH_LOG("Failed to initialize audit: %s", error_msg);
838 	}
839 
840 	/* Applies test filter for the bin_wait_pipe_sandbox program. */
841 	EXPECT_EQ(0, audit_init_filter_exe(&self->audit_filter,
842 					   bin_wait_pipe_sandbox));
843 	EXPECT_EQ(0, audit_filter_exe(self->audit_fd, &self->audit_filter,
844 				      AUDIT_ADD_RULE));
845 
846 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
847 }
848 
849 FIXTURE_TEARDOWN(audit_exec)
850 {
851 	set_cap(_metadata, CAP_AUDIT_CONTROL);
852 	EXPECT_EQ(0, audit_filter_exe(self->audit_fd, &self->audit_filter,
853 				      AUDIT_DEL_RULE));
854 	clear_cap(_metadata, CAP_AUDIT_CONTROL);
855 	EXPECT_EQ(0, close(self->audit_fd));
856 }
857 
858 TEST_F(audit_exec, signal_and_open)
859 {
860 	struct audit_records records;
861 	int pipe_child[2], pipe_parent[2];
862 	char buf_parent;
863 	pid_t child;
864 	int status;
865 
866 	ASSERT_EQ(0, pipe2(pipe_child, 0));
867 	ASSERT_EQ(0, pipe2(pipe_parent, 0));
868 
869 	child = fork();
870 	ASSERT_LE(0, child);
871 	if (child == 0) {
872 		const struct landlock_ruleset_attr layer1 = {
873 			.scoped = LANDLOCK_SCOPE_SIGNAL,
874 		};
875 		char pipe_child_str[12], pipe_parent_str[12];
876 		char *const argv[] = { (char *)bin_wait_pipe_sandbox,
877 				       pipe_child_str, pipe_parent_str, NULL };
878 		int ruleset_fd;
879 
880 		/* Passes the pipe FDs to the executed binary. */
881 		EXPECT_EQ(0, close(pipe_child[0]));
882 		EXPECT_EQ(0, close(pipe_parent[1]));
883 		snprintf(pipe_child_str, sizeof(pipe_child_str), "%d",
884 			 pipe_child[1]);
885 		snprintf(pipe_parent_str, sizeof(pipe_parent_str), "%d",
886 			 pipe_parent[0]);
887 
888 		ruleset_fd =
889 			landlock_create_ruleset(&layer1, sizeof(layer1), 0);
890 		if (ruleset_fd < 0) {
891 			perror("Failed to create a ruleset");
892 			_exit(1);
893 		}
894 		prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0);
895 		if (landlock_restrict_self(ruleset_fd,
896 					   variant->restrict_flags)) {
897 			perror("Failed to restrict self");
898 			_exit(1);
899 		}
900 		close(ruleset_fd);
901 
902 		ASSERT_EQ(0, execve(argv[0], argv, NULL))
903 		{
904 			TH_LOG("Failed to execute \"%s\": %s", argv[0],
905 			       strerror(errno));
906 		};
907 		_exit(1);
908 		return;
909 	}
910 
911 	EXPECT_EQ(0, close(pipe_child[1]));
912 	EXPECT_EQ(0, close(pipe_parent[0]));
913 
914 	/* Waits for the child. */
915 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
916 
917 	/* Tests that there was no denial until now. */
918 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
919 	EXPECT_EQ(0, records.access);
920 
921 	/*
922 	 * Wait for the child to do a first denied action by layer1 and
923 	 * sandbox itself with layer2.
924 	 */
925 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
926 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
927 
928 	/* Tests that the audit record only matches the child. */
929 	if (variant->restrict_flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON) {
930 		/* Matches the current domain. */
931 		EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
932 						getpid(), NULL));
933 	}
934 
935 	/* Checks that we didn't miss anything. */
936 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
937 	EXPECT_EQ(0, records.access);
938 
939 	/*
940 	 * Wait for the child to do a second denied action by layer1 and
941 	 * layer2, and sandbox itself with layer3.
942 	 */
943 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
944 	EXPECT_EQ(1, read(pipe_child[0], &buf_parent, 1));
945 
946 	/* Tests that the audit record only matches the child. */
947 	if (variant->restrict_flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON) {
948 		/* Matches the current domain. */
949 		EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
950 						getpid(), NULL));
951 	}
952 
953 	if (!(variant->restrict_flags &
954 	      LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) {
955 		/* Matches the child domain. */
956 		EXPECT_EQ(0, matches_log_fs_read_root(self->audit_fd));
957 	}
958 
959 	/* Checks that we didn't miss anything. */
960 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
961 	EXPECT_EQ(0, records.access);
962 
963 	/* Waits for the child to terminate. */
964 	EXPECT_EQ(1, write(pipe_parent[1], ".", 1));
965 	ASSERT_EQ(child, waitpid(child, &status, 0));
966 	ASSERT_EQ(1, WIFEXITED(status));
967 	ASSERT_EQ(0, WEXITSTATUS(status));
968 
969 	/* Tests that the audit record only matches the child. */
970 	if (!(variant->restrict_flags &
971 	      LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) {
972 		/*
973 		 * Matches the child domains, which tests that the
974 		 * llcred->domain_exec bitmask is correctly updated with a new
975 		 * domain.
976 		 */
977 		EXPECT_EQ(0, matches_log_fs_read_root(self->audit_fd));
978 		EXPECT_EQ(0, matches_log_signal(_metadata, self->audit_fd,
979 						getpid(), NULL));
980 	}
981 
982 	/* Checks that we didn't miss anything. */
983 	EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
984 	EXPECT_EQ(0, records.access);
985 }
986 
987 TEST_HARNESS_MAIN
988