[PATCH v2 5/6] selftests/landlock: Repurpose scoped_abstract_unix_test.c for pathname sockets too.
Tingmao Wang
m at maowtm.org
Mon Feb 2 00:06:02 UTC 2026
On 1/29/26 21:28, Mickaël Salaün wrote:
> [...]
> On Tue, Dec 30, 2025 at 05:20:23PM +0000, Tingmao Wang wrote:
>> [...]
>> @@ -308,6 +413,12 @@ TEST_F(scoped_audit, connect_to_child)
>> char buf;
>> int dgram_client;
>> struct audit_records records;
>> + struct service_fixture *const dgram_address =
>> + variant->abstract_socket ? &self->dgram_address_abstract :
>> + &self->dgram_address_pathname;
>> + size_t log_match_remaining = 500;
>
> const
>
> Why this number? Could you please follow the same logic as in
> matches_log_fs_extra()?
It's not a const since we decrement it below as we fill log_match with
stpncpy().
matches_log_fs_extra() uses 2*PATH_MAX + length of various fixed strings.
I guess since the path is a resolved absolute path which can vary based on
where this test is ran, it is safest to use a value based on PATH_MAX. I
will update.
>
>> + char log_match[log_match_remaining];
>> + char *log_match_cursor = log_match;
>>
>> /* Makes sure there is no superfluous logged records. */
>> EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
>> @@ -330,8 +441,8 @@ TEST_F(scoped_audit, connect_to_child)
>>
>> dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
>> ASSERT_LE(0, dgram_server);
>> - ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
>> - self->dgram_address.unix_addr_len));
>> + ASSERT_EQ(0, bind(dgram_server, &dgram_address->unix_addr,
>> + dgram_address->unix_addr_len));
>>
>> /* Signals to the parent that child is listening. */
>> ASSERT_EQ(1, write(pipe_child[1], ".", 1));
>> @@ -345,7 +456,9 @@ 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);
>> + create_scoped_domain(_metadata,
>> + LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET |
>> + LANDLOCK_SCOPE_PATHNAME_UNIX_SOCKET);
>>
>> /* Signals that the parent is in a domain, if any. */
>> ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
>> @@ -355,19 +468,62 @@ TEST_F(scoped_audit, connect_to_child)
>>
>> /* Waits for the child to listen */
>> ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
>> - err_dgram = connect(dgram_client, &self->dgram_address.unix_addr,
>> - self->dgram_address.unix_addr_len);
>> + err_dgram = connect(dgram_client, &dgram_address->unix_addr,
>> + dgram_address->unix_addr_len);
>> EXPECT_EQ(-1, err_dgram);
>> EXPECT_EQ(EPERM, errno);
>>
>> - EXPECT_EQ(
>> - 0,
>> - audit_match_record(
>> - self->audit_fd, AUDIT_LANDLOCK_ACCESS,
>> + if (variant->abstract_socket) {
>> + log_match_cursor = stpncpy(
>> + log_match,
>> REGEX_LANDLOCK_PREFIX
>> " blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
>> "[0-9A-F]\\+$",
>> - NULL));
>> + log_match_remaining);
>> + log_match_remaining =
>> + sizeof(log_match) - (log_match_cursor - log_match);
>> + ASSERT_NE(0, log_match_remaining);
>> + } else {
>> + /*
>> + * It is assumed that absolute_path does not contain control
>> + * characters nor spaces, see audit_string_contains_control().
>> + */
>> + char *absolute_path =
>
> const char *absolute_path
Can't use const char * here since we free() it later:
scoped_unix_test.c:513:22: warning: passing argument 1 of ‘free’ discards ‘const’ qualifier from pointer target type [-Wdiscarded-qualifiers]
513 | free(absolute_path);
| ^~~~~~~~~~~~~
But I guess we can char *const. Will update to:
char *const absolute_path =
realpath(dgram_address->unix_addr.sun_path, NULL);
>
>> + realpath(dgram_address->unix_addr.sun_path, NULL);
>> +
>> + EXPECT_NE(NULL, absolute_path)
>> + {
>> + TH_LOG("realpath() failed: %s", strerror(errno));
>> + return;
>> + }
>> +
>> + log_match_cursor =
>> + stpncpy(log_match,
>> + REGEX_LANDLOCK_PREFIX
>> + " blockers=scope\\.pathname_unix_socket path=\"",
>> + log_match_remaining);
>> + log_match_remaining =
>> + sizeof(log_match) - (log_match_cursor - log_match);
>> + ASSERT_NE(0, log_match_remaining);
>> + log_match_cursor = regex_escape(absolute_path, log_match_cursor,
>> + log_match_remaining);
>> + free(absolute_path);
>> + if (log_match_cursor < 0) {
>> + TH_LOG("regex_escape() failed (buffer too small)");
>> + return;
>> + }
>> + log_match_remaining =
>> + sizeof(log_match) - (log_match_cursor - log_match);
>> + ASSERT_NE(0, log_match_remaining);
>> + log_match_cursor =
>> + stpncpy(log_match_cursor, "\"$", log_match_remaining);
>> + log_match_remaining =
>> + sizeof(log_match) - (log_match_cursor - log_match);
>> + ASSERT_NE(0, log_match_remaining);
>> + }
>> +
>> + EXPECT_EQ(0, audit_match_record(self->audit_fd, AUDIT_LANDLOCK_ACCESS,
>> + log_match, NULL));
>>
>> ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
>> EXPECT_EQ(0, close(dgram_client));
>> --
>> 2.52.0
>>
>>
More information about the Linux-security-module-archive
mailing list