Skip to content

Commit e115687

Browse files
committed
selftests/landlock: Add audit tests for abstract UNIX socket scoping
Add a new scoped_audit.connect_to_child test to check the abstract UNIX socket blocker. Cc: Günther Noack <gnoack@google.com> Cc: Paul Moore <paul@paul-moore.com> Link: https://lore.kernel.org/r/20250320190717.2287696-26-mic@digikod.net Signed-off-by: Mickaël Salaün <mic@digikod.net>
1 parent e2893c0 commit e115687

File tree

1 file changed

+111
-0
lines changed

1 file changed

+111
-0
lines changed

tools/testing/selftests/landlock/scoped_abstract_unix_test.c

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include <sys/wait.h>
2121
#include <unistd.h>
2222

23+
#include "audit.h"
2324
#include "common.h"
2425
#include "scoped_common.h"
2526

@@ -267,6 +268,116 @@ TEST_F(scoped_domains, connect_to_child)
267268
_metadata->exit_code = KSFT_FAIL;
268269
}
269270

271+
FIXTURE(scoped_audit)
272+
{
273+
struct service_fixture dgram_address;
274+
struct audit_filter audit_filter;
275+
int audit_fd;
276+
};
277+
278+
FIXTURE_SETUP(scoped_audit)
279+
{
280+
disable_caps(_metadata);
281+
282+
memset(&self->dgram_address, 0, sizeof(self->dgram_address));
283+
set_unix_address(&self->dgram_address, 1);
284+
285+
set_cap(_metadata, CAP_AUDIT_CONTROL);
286+
self->audit_fd = audit_init_with_exe_filter(&self->audit_filter);
287+
EXPECT_LE(0, self->audit_fd);
288+
drop_caps(_metadata);
289+
}
290+
291+
FIXTURE_TEARDOWN_PARENT(scoped_audit)
292+
{
293+
EXPECT_EQ(0, audit_cleanup(-1, NULL));
294+
}
295+
296+
/* python -c 'print(b"\0selftests-landlock-abstract-unix-".hex().upper())' */
297+
#define ABSTRACT_SOCKET_PATH_PREFIX \
298+
"0073656C6674657374732D6C616E646C6F636B2D61627374726163742D756E69782D"
299+
300+
/*
301+
* Simpler version of scoped_domains.connect_to_child, but with audit tests.
302+
*/
303+
TEST_F(scoped_audit, connect_to_child)
304+
{
305+
pid_t child;
306+
int err_dgram, status;
307+
int pipe_child[2], pipe_parent[2];
308+
char buf;
309+
int dgram_client;
310+
struct audit_records records;
311+
312+
/* Makes sure there is no superfluous logged records. */
313+
EXPECT_EQ(0, audit_count_records(self->audit_fd, &records));
314+
EXPECT_EQ(0, records.access);
315+
EXPECT_EQ(0, records.domain);
316+
317+
ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));
318+
ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
319+
320+
child = fork();
321+
ASSERT_LE(0, child);
322+
if (child == 0) {
323+
int dgram_server;
324+
325+
EXPECT_EQ(0, close(pipe_parent[1]));
326+
EXPECT_EQ(0, close(pipe_child[0]));
327+
328+
/* Waits for the parent to be in a domain. */
329+
ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
330+
331+
dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0);
332+
ASSERT_LE(0, dgram_server);
333+
ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr,
334+
self->dgram_address.unix_addr_len));
335+
336+
/* Signals to the parent that child is listening. */
337+
ASSERT_EQ(1, write(pipe_child[1], ".", 1));
338+
339+
/* Waits to connect. */
340+
ASSERT_EQ(1, read(pipe_parent[0], &buf, 1));
341+
EXPECT_EQ(0, close(dgram_server));
342+
_exit(_metadata->exit_code);
343+
return;
344+
}
345+
EXPECT_EQ(0, close(pipe_child[1]));
346+
EXPECT_EQ(0, close(pipe_parent[0]));
347+
348+
create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
349+
350+
/* Signals that the parent is in a domain, if any. */
351+
ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
352+
353+
dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0);
354+
ASSERT_LE(0, dgram_client);
355+
356+
/* Waits for the child to listen */
357+
ASSERT_EQ(1, read(pipe_child[0], &buf, 1));
358+
err_dgram = connect(dgram_client, &self->dgram_address.unix_addr,
359+
self->dgram_address.unix_addr_len);
360+
EXPECT_EQ(-1, err_dgram);
361+
EXPECT_EQ(EPERM, errno);
362+
363+
EXPECT_EQ(
364+
0,
365+
audit_match_record(
366+
self->audit_fd, AUDIT_LANDLOCK_ACCESS,
367+
REGEX_LANDLOCK_PREFIX
368+
" blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX
369+
"[0-9A-F]\\+$",
370+
NULL));
371+
372+
ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
373+
EXPECT_EQ(0, close(dgram_client));
374+
375+
ASSERT_EQ(child, waitpid(child, &status, 0));
376+
if (WIFSIGNALED(status) || !WIFEXITED(status) ||
377+
WEXITSTATUS(status) != EXIT_SUCCESS)
378+
_metadata->exit_code = KSFT_FAIL;
379+
}
380+
270381
FIXTURE(scoped_vs_unscoped)
271382
{
272383
struct service_fixture parent_stream_address, parent_dgram_address,

0 commit comments

Comments
 (0)