|
20 | 20 | #include <sys/wait.h>
|
21 | 21 | #include <unistd.h>
|
22 | 22 |
|
| 23 | +#include "audit.h" |
23 | 24 | #include "common.h"
|
24 | 25 | #include "scoped_common.h"
|
25 | 26 |
|
@@ -267,6 +268,116 @@ TEST_F(scoped_domains, connect_to_child)
|
267 | 268 | _metadata->exit_code = KSFT_FAIL;
|
268 | 269 | }
|
269 | 270 |
|
| 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 | + |
270 | 381 | FIXTURE(scoped_vs_unscoped)
|
271 | 382 | {
|
272 | 383 | struct service_fixture parent_stream_address, parent_dgram_address,
|
|
0 commit comments