selftests/landlock: Add tests for quiet flag with scope

Enhance scoped_audit.connect_to_child and audit_flags.signal to test
interaction with various quiet flag settings.

Signed-off-by: Tingmao Wang <m@maowtm.org>
Link: https://patch.msgid.link/032849ca97bd45b2e14f96192b61537ed9405a0d.1781228815.git.m@maowtm.org
[mic: Fix comment formatting]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
This commit is contained in:
Tingmao Wang 2026-06-12 02:48:54 +01:00 committed by Mickaël Salaün
parent 624c96268b
commit 1493675453
No known key found for this signature in database
GPG Key ID: E5E3D0E88C82F6D2
2 changed files with 87 additions and 15 deletions

View File

@ -607,30 +607,42 @@ FIXTURE(audit_flags)
FIXTURE_VARIANT(audit_flags)
{
const int restrict_flags;
const __u64 quiet_scoped;
};
/* clang-format off */
FIXTURE_VARIANT_ADD(audit_flags, default) {
/* clang-format on */
.restrict_flags = 0,
.quiet_scoped = 0,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(audit_flags, same_exec_off) {
/* clang-format on */
.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF,
.quiet_scoped = 0,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(audit_flags, subdomains_off) {
/* clang-format on */
.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF,
.quiet_scoped = 0,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(audit_flags, cross_exec_on) {
/* clang-format on */
.restrict_flags = LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON,
.quiet_scoped = 0,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(audit_flags, signal_quieted) {
/* clang-format on */
.restrict_flags = 0,
.quiet_scoped = LANDLOCK_SCOPE_SIGNAL,
};
FIXTURE_SETUP(audit_flags)
@ -674,12 +686,16 @@ TEST_F(audit_flags, signal)
pid_t child;
struct audit_records records;
__u64 deallocated_dom = 2;
bool expect_audit = !(variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) &&
!(variant->quiet_scoped & LANDLOCK_SCOPE_SIGNAL);
child = fork();
ASSERT_LE(0, child);
if (child == 0) {
const struct landlock_ruleset_attr ruleset_attr = {
.scoped = LANDLOCK_SCOPE_SIGNAL,
.quiet_scoped = variant->quiet_scoped,
};
int ruleset_fd;
@ -696,8 +712,7 @@ TEST_F(audit_flags, signal)
EXPECT_EQ(-1, kill(getppid(), 0));
EXPECT_EQ(EPERM, errno);
if (variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
if (!expect_audit) {
EXPECT_EQ(-EAGAIN, matches_log_signal(
_metadata, self->audit_fd,
getppid(), self->domain_id));
@ -724,8 +739,7 @@ TEST_F(audit_flags, signal)
/* Makes sure there is no superfluous logged records. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
if (variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
if (!expect_audit) {
EXPECT_EQ(0, records.access);
} else {
EXPECT_EQ(1, records.access);
@ -749,8 +763,7 @@ TEST_F(audit_flags, signal)
WEXITSTATUS(status) != EXIT_SUCCESS)
_metadata->exit_code = KSFT_FAIL;
if (variant->restrict_flags &
LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF) {
if (!expect_audit) {
/*
* No deallocation record: denials=0 never matches a real
* record.

View File

@ -293,6 +293,45 @@ FIXTURE_TEARDOWN_PARENT(scoped_audit)
EXPECT_EQ(0, audit_cleanup(-1, NULL));
}
FIXTURE_VARIANT(scoped_audit)
{
const __u64 scoped;
const __u64 quiet_scoped;
};
/* clang-format off */
FIXTURE_VARIANT_ADD(scoped_audit, no_quiet)
{
/* clang-format on */
.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
.quiet_scoped = 0,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(scoped_audit, quiet_abstract_socket)
{
/* clang-format on */
.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
.quiet_scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(scoped_audit, quiet_abstract_socket_2)
{
/* clang-format on */
.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL,
.quiet_scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
LANDLOCK_SCOPE_SIGNAL,
};
/* clang-format off */
FIXTURE_VARIANT_ADD(scoped_audit, quiet_unrelated)
{
/* clang-format on */
.scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL,
.quiet_scoped = LANDLOCK_SCOPE_SIGNAL,
};
/* python -c 'print(b"\0selftests-landlock-abstract-unix-".hex().upper())' */
#define ABSTRACT_SOCKET_PATH_PREFIX \
"0073656C6674657374732D6C616E646C6F636B2D61627374726163742D756E69782D"
@ -308,6 +347,13 @@ TEST_F(scoped_audit, connect_to_child)
char buf;
int dgram_client;
struct audit_records records;
int ruleset_fd;
const struct landlock_ruleset_attr ruleset_attr = {
.scoped = variant->scoped,
.quiet_scoped = variant->quiet_scoped,
};
bool should_audit =
!(variant->quiet_scoped & LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
/* Makes sure there is no superfluous logged records. */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
@ -345,7 +391,14 @@ TEST_F(scoped_audit, connect_to_child)
EXPECT_EQ(0, close(pipe_child[1]));
EXPECT_EQ(0, close(pipe_parent[0]));
create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
ruleset_fd =
landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0);
ASSERT_LE(0, ruleset_fd)
{
TH_LOG("Failed to create a ruleset: %s", strerror(errno));
}
enforce_ruleset(_metadata, ruleset_fd);
EXPECT_EQ(0, close(ruleset_fd));
/* Signals that the parent is in a domain, if any. */
ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
@ -360,14 +413,20 @@ TEST_F(scoped_audit, connect_to_child)
EXPECT_EQ(-1, err_dgram);
EXPECT_EQ(EPERM, errno);
EXPECT_EQ(
0,
audit_match_record(
self->audit_fd, AUDIT_LANDLOCK_ACCESS,
REGEX_LANDLOCK_PREFIX
" blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
"[0-9A-F]\\+$",
NULL));
if (should_audit) {
EXPECT_EQ(
0,
audit_match_record(
self->audit_fd, AUDIT_LANDLOCK_ACCESS,
REGEX_LANDLOCK_PREFIX
" blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
"[0-9A-F]\\+$",
NULL));
}
/* No other logs */
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
EXPECT_EQ(0, records.access);
ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
EXPECT_EQ(0, close(dgram_client));