Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

selftests/landlock: Drain stale audit records on init

Non-audit Landlock tests generate audit records as side effects when
audit_enabled is non-zero (e.g. from boot configuration). These records
accumulate in the kernel audit backlog while no audit daemon socket is
open. When the next test opens a new netlink socket and registers as
the audit daemon, the stale backlog is delivered, causing baseline
record count checks to fail spuriously.

Fix this by draining all pending records in audit_init() right after
setting the receive timeout. The 1-usec SO_RCVTIMEO causes audit_recv()
to return -EAGAIN once the backlog is empty, naturally terminating the
drain loop.

Domain deallocation records are emitted asynchronously from a work
queue, so they may still arrive after the drain. Remove records.domain
== 0 checks that are not preceded by audit_match_record() calls, which
would otherwise consume stale records before the count. Document this
constraint above audit_count_records().

Increasing the drain timeout to catch in-flight deallocation records was
considered but rejected: a longer timeout adds latency to every
audit_init() call even when no stale record is pending, and any fixed
timeout is still not guaranteed to catch all records under load.
Removing the unprotected checks is simpler and avoids the spurious
failures.

Cc: Günther Noack <gnoack@google.com>
Cc: stable@vger.kernel.org
Fixes: 6a500b22971c ("selftests/landlock: Add tests for audit flags and domain IDs")
Reviewed-by: Günther Noack <gnoack3000@gmail.com>
Link: https://lore.kernel.org/r/20260402192608.1458252-4-mic@digikod.net
Signed-off-by: Mickaël Salaün <mic@digikod.net>

+19 -4
+19
tools/testing/selftests/landlock/audit.h
··· 338 338 size_t domain; 339 339 }; 340 340 341 + /* 342 + * WARNING: Do not assert records.domain == 0 without a preceding 343 + * audit_match_record() call. Domain deallocation records are emitted 344 + * asynchronously from kworker threads and can arrive after the drain in 345 + * audit_init(), corrupting the domain count. A preceding audit_match_record() 346 + * call consumes stale records while scanning, making the assertion safe in 347 + * practice because stale deallocation records arrive before the expected access 348 + * records. 349 + */ 341 350 static int audit_count_records(int audit_fd, struct audit_records *records) 342 351 { 343 352 struct audit_message msg; ··· 401 392 err = -errno; 402 393 goto err_close; 403 394 } 395 + 396 + /* 397 + * Drains stale audit records that accumulated in the kernel backlog 398 + * while no audit daemon socket was open. This happens when non-audit 399 + * Landlock tests generate records while audit_enabled is non-zero (e.g. 400 + * from boot configuration), or when domain deallocation records arrive 401 + * asynchronously after a previous test's socket was closed. 402 + */ 403 + while (audit_recv(fd, NULL) == 0) 404 + ; 404 405 405 406 return fd; 406 407
-2
tools/testing/selftests/landlock/audit_test.c
··· 733 733 } else { 734 734 EXPECT_EQ(1, records.access); 735 735 } 736 - EXPECT_EQ(0, records.domain); 737 736 738 737 /* Updates filter rules to match the drop record. */ 739 738 set_cap(_metadata, CAP_AUDIT_CONTROL); ··· 921 922 /* Tests that there was no denial until now. */ 922 923 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 923 924 EXPECT_EQ(0, records.access); 924 - EXPECT_EQ(0, records.domain); 925 925 926 926 /* 927 927 * Wait for the child to do a first denied action by layer1 and
-1
tools/testing/selftests/landlock/ptrace_test.c
··· 342 342 /* Makes sure there is no superfluous logged records. */ 343 343 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 344 344 EXPECT_EQ(0, records.access); 345 - EXPECT_EQ(0, records.domain); 346 345 347 346 yama_ptrace_scope = get_yama_ptrace_scope(); 348 347 ASSERT_LE(0, yama_ptrace_scope);
-1
tools/testing/selftests/landlock/scoped_abstract_unix_test.c
··· 312 312 /* Makes sure there is no superfluous logged records. */ 313 313 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 314 314 EXPECT_EQ(0, records.access); 315 - EXPECT_EQ(0, records.domain); 316 315 317 316 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 318 317 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));