1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Landlock tests - Abstract UNIX socket 4 * 5 * Copyright © 2024 Tahera Fahimi <fahimitahera@gmail.com> 6 */ 7 8 #define _GNU_SOURCE 9 #include <errno.h> 10 #include <fcntl.h> 11 #include <linux/landlock.h> 12 #include <sched.h> 13 #include <signal.h> 14 #include <stddef.h> 15 #include <sys/prctl.h> 16 #include <sys/socket.h> 17 #include <sys/stat.h> 18 #include <sys/types.h> 19 #include <sys/un.h> 20 #include <sys/wait.h> 21 #include <unistd.h> 22 23 #include "audit.h" 24 #include "common.h" 25 #include "scoped_common.h" 26 27 /* Number of pending connections queue to be hold. */ 28 const short backlog = 10; 29 30 static void create_fs_domain(struct __test_metadata *const _metadata) 31 { 32 int ruleset_fd; 33 struct landlock_ruleset_attr ruleset_attr = { 34 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 35 }; 36 37 ruleset_fd = 38 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 39 EXPECT_LE(0, ruleset_fd) 40 { 41 TH_LOG("Failed to create a ruleset: %s", strerror(errno)); 42 } 43 EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); 44 EXPECT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); 45 EXPECT_EQ(0, close(ruleset_fd)); 46 } 47 48 FIXTURE(scoped_domains) 49 { 50 struct service_fixture stream_address, dgram_address; 51 }; 52 53 #include "scoped_base_variants.h" 54 55 FIXTURE_SETUP(scoped_domains) 56 { 57 drop_caps(_metadata); 58 59 memset(&self->stream_address, 0, sizeof(self->stream_address)); 60 memset(&self->dgram_address, 0, sizeof(self->dgram_address)); 61 set_unix_address(&self->stream_address, 0); 62 set_unix_address(&self->dgram_address, 1); 63 } 64 65 FIXTURE_TEARDOWN(scoped_domains) 66 { 67 } 68 69 /* 70 * Test unix_stream_connect() and unix_may_send() for a child connecting to its 71 * parent, when they have scoped domain or no domain. 72 */ 73 TEST_F(scoped_domains, connect_to_parent) 74 { 75 pid_t child; 76 bool can_connect_to_parent; 77 int status; 78 int pipe_parent[2]; 79 int stream_server, dgram_server; 80 81 /* 82 * can_connect_to_parent is true if a child process can connect to its 83 * parent process. This depends on the child process not being isolated 84 * from the parent with a dedicated Landlock domain. 85 */ 86 can_connect_to_parent = !variant->domain_child; 87 88 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 89 if (variant->domain_both) { 90 create_scoped_domain(_metadata, 91 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 92 if (!__test_passed(_metadata)) 93 return; 94 } 95 96 child = fork(); 97 ASSERT_LE(0, child); 98 if (child == 0) { 99 int err; 100 int stream_client, dgram_client; 101 char buf_child; 102 103 EXPECT_EQ(0, close(pipe_parent[1])); 104 if (variant->domain_child) 105 create_scoped_domain( 106 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 107 108 stream_client = socket(AF_UNIX, SOCK_STREAM, 0); 109 ASSERT_LE(0, stream_client); 110 dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0); 111 ASSERT_LE(0, dgram_client); 112 113 /* Waits for the server. */ 114 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1)); 115 116 err = connect(stream_client, &self->stream_address.unix_addr, 117 self->stream_address.unix_addr_len); 118 if (can_connect_to_parent) { 119 EXPECT_EQ(0, err); 120 } else { 121 EXPECT_EQ(-1, err); 122 EXPECT_EQ(EPERM, errno); 123 } 124 EXPECT_EQ(0, close(stream_client)); 125 126 err = connect(dgram_client, &self->dgram_address.unix_addr, 127 self->dgram_address.unix_addr_len); 128 if (can_connect_to_parent) { 129 EXPECT_EQ(0, err); 130 } else { 131 EXPECT_EQ(-1, err); 132 EXPECT_EQ(EPERM, errno); 133 } 134 EXPECT_EQ(0, close(dgram_client)); 135 _exit(_metadata->exit_code); 136 return; 137 } 138 EXPECT_EQ(0, close(pipe_parent[0])); 139 if (variant->domain_parent) 140 create_scoped_domain(_metadata, 141 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 142 143 stream_server = socket(AF_UNIX, SOCK_STREAM, 0); 144 ASSERT_LE(0, stream_server); 145 dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0); 146 ASSERT_LE(0, dgram_server); 147 ASSERT_EQ(0, bind(stream_server, &self->stream_address.unix_addr, 148 self->stream_address.unix_addr_len)); 149 ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr, 150 self->dgram_address.unix_addr_len)); 151 ASSERT_EQ(0, listen(stream_server, backlog)); 152 153 /* Signals to child that the parent is listening. */ 154 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 155 156 ASSERT_EQ(child, waitpid(child, &status, 0)); 157 EXPECT_EQ(0, close(stream_server)); 158 EXPECT_EQ(0, close(dgram_server)); 159 160 if (WIFSIGNALED(status) || !WIFEXITED(status) || 161 WEXITSTATUS(status) != EXIT_SUCCESS) 162 _metadata->exit_code = KSFT_FAIL; 163 } 164 165 /* 166 * Test unix_stream_connect() and unix_may_send() for a parent connecting to 167 * its child, when they have scoped domain or no domain. 168 */ 169 TEST_F(scoped_domains, connect_to_child) 170 { 171 pid_t child; 172 bool can_connect_to_child; 173 int err_stream, err_dgram, errno_stream, errno_dgram, status; 174 int pipe_child[2], pipe_parent[2]; 175 char buf; 176 int stream_client, dgram_client; 177 178 /* 179 * can_connect_to_child is true if a parent process can connect to its 180 * child process. The parent process is not isolated from the child 181 * with a dedicated Landlock domain. 182 */ 183 can_connect_to_child = !variant->domain_parent; 184 185 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 186 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 187 if (variant->domain_both) { 188 create_scoped_domain(_metadata, 189 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 190 if (!__test_passed(_metadata)) 191 return; 192 } 193 194 child = fork(); 195 ASSERT_LE(0, child); 196 if (child == 0) { 197 int stream_server, dgram_server; 198 199 EXPECT_EQ(0, close(pipe_parent[1])); 200 EXPECT_EQ(0, close(pipe_child[0])); 201 if (variant->domain_child) 202 create_scoped_domain( 203 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 204 205 /* Waits for the parent to be in a domain, if any. */ 206 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 207 208 stream_server = socket(AF_UNIX, SOCK_STREAM, 0); 209 ASSERT_LE(0, stream_server); 210 dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0); 211 ASSERT_LE(0, dgram_server); 212 ASSERT_EQ(0, 213 bind(stream_server, &self->stream_address.unix_addr, 214 self->stream_address.unix_addr_len)); 215 ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr, 216 self->dgram_address.unix_addr_len)); 217 ASSERT_EQ(0, listen(stream_server, backlog)); 218 219 /* Signals to the parent that child is listening. */ 220 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 221 222 /* Waits to connect. */ 223 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 224 EXPECT_EQ(0, close(stream_server)); 225 EXPECT_EQ(0, close(dgram_server)); 226 _exit(_metadata->exit_code); 227 return; 228 } 229 EXPECT_EQ(0, close(pipe_child[1])); 230 EXPECT_EQ(0, close(pipe_parent[0])); 231 232 if (variant->domain_parent) 233 create_scoped_domain(_metadata, 234 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 235 236 /* Signals that the parent is in a domain, if any. */ 237 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 238 239 stream_client = socket(AF_UNIX, SOCK_STREAM, 0); 240 ASSERT_LE(0, stream_client); 241 dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0); 242 ASSERT_LE(0, dgram_client); 243 244 /* Waits for the child to listen */ 245 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 246 err_stream = connect(stream_client, &self->stream_address.unix_addr, 247 self->stream_address.unix_addr_len); 248 errno_stream = errno; 249 err_dgram = connect(dgram_client, &self->dgram_address.unix_addr, 250 self->dgram_address.unix_addr_len); 251 errno_dgram = errno; 252 if (can_connect_to_child) { 253 EXPECT_EQ(0, err_stream); 254 EXPECT_EQ(0, err_dgram); 255 } else { 256 EXPECT_EQ(-1, err_stream); 257 EXPECT_EQ(-1, err_dgram); 258 EXPECT_EQ(EPERM, errno_stream); 259 EXPECT_EQ(EPERM, errno_dgram); 260 } 261 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 262 EXPECT_EQ(0, close(stream_client)); 263 EXPECT_EQ(0, close(dgram_client)); 264 265 ASSERT_EQ(child, waitpid(child, &status, 0)); 266 if (WIFSIGNALED(status) || !WIFEXITED(status) || 267 WEXITSTATUS(status) != EXIT_SUCCESS) 268 _metadata->exit_code = KSFT_FAIL; 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 FIXTURE_VARIANT(scoped_audit) 297 { 298 const __u64 scoped; 299 const __u64 quiet_scoped; 300 }; 301 302 /* clang-format off */ 303 FIXTURE_VARIANT_ADD(scoped_audit, no_quiet) 304 { 305 /* clang-format on */ 306 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, 307 .quiet_scoped = 0, 308 }; 309 310 /* clang-format off */ 311 FIXTURE_VARIANT_ADD(scoped_audit, quiet_abstract_socket) 312 { 313 /* clang-format on */ 314 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, 315 .quiet_scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, 316 }; 317 318 /* clang-format off */ 319 FIXTURE_VARIANT_ADD(scoped_audit, quiet_abstract_socket_2) 320 { 321 /* clang-format on */ 322 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL, 323 .quiet_scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | 324 LANDLOCK_SCOPE_SIGNAL, 325 }; 326 327 /* clang-format off */ 328 FIXTURE_VARIANT_ADD(scoped_audit, quiet_unrelated) 329 { 330 /* clang-format on */ 331 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET | LANDLOCK_SCOPE_SIGNAL, 332 .quiet_scoped = LANDLOCK_SCOPE_SIGNAL, 333 }; 334 335 /* python -c 'print(b"\0selftests-landlock-abstract-unix-".hex().upper())' */ 336 #define ABSTRACT_SOCKET_PATH_PREFIX \ 337 "0073656C6674657374732D6C616E646C6F636B2D61627374726163742D756E69782D" 338 339 /* 340 * Simpler version of scoped_domains.connect_to_child, but with audit tests. 341 */ 342 TEST_F(scoped_audit, connect_to_child) 343 { 344 pid_t child; 345 int err_dgram, status; 346 int pipe_child[2], pipe_parent[2]; 347 char buf; 348 int dgram_client; 349 struct audit_records records; 350 int ruleset_fd; 351 const struct landlock_ruleset_attr ruleset_attr = { 352 .scoped = variant->scoped, 353 .quiet_scoped = variant->quiet_scoped, 354 }; 355 bool should_audit = 356 !(variant->quiet_scoped & LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 357 358 /* Makes sure there is no superfluous logged records. */ 359 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 360 EXPECT_EQ(0, records.access); 361 EXPECT_EQ(0, records.domain); 362 363 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 364 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 365 366 child = fork(); 367 ASSERT_LE(0, child); 368 if (child == 0) { 369 int dgram_server; 370 371 EXPECT_EQ(0, close(pipe_parent[1])); 372 EXPECT_EQ(0, close(pipe_child[0])); 373 374 /* Waits for the parent to be in a domain. */ 375 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 376 377 dgram_server = socket(AF_UNIX, SOCK_DGRAM, 0); 378 ASSERT_LE(0, dgram_server); 379 ASSERT_EQ(0, bind(dgram_server, &self->dgram_address.unix_addr, 380 self->dgram_address.unix_addr_len)); 381 382 /* Signals to the parent that child is listening. */ 383 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 384 385 /* Waits to connect. */ 386 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 387 EXPECT_EQ(0, close(dgram_server)); 388 _exit(_metadata->exit_code); 389 return; 390 } 391 EXPECT_EQ(0, close(pipe_child[1])); 392 EXPECT_EQ(0, close(pipe_parent[0])); 393 394 ruleset_fd = 395 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 396 ASSERT_LE(0, ruleset_fd) 397 { 398 TH_LOG("Failed to create a ruleset: %s", strerror(errno)); 399 } 400 enforce_ruleset(_metadata, ruleset_fd); 401 EXPECT_EQ(0, close(ruleset_fd)); 402 403 /* Signals that the parent is in a domain, if any. */ 404 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 405 406 dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0); 407 ASSERT_LE(0, dgram_client); 408 409 /* Waits for the child to listen */ 410 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 411 err_dgram = connect(dgram_client, &self->dgram_address.unix_addr, 412 self->dgram_address.unix_addr_len); 413 EXPECT_EQ(-1, err_dgram); 414 EXPECT_EQ(EPERM, errno); 415 416 if (should_audit) { 417 EXPECT_EQ( 418 0, 419 audit_match_record( 420 self->audit_fd, AUDIT_LANDLOCK_ACCESS, 421 REGEX_LANDLOCK_PREFIX 422 " blockers=scope\\.abstract_unix_socket path=" ABSTRACT_SOCKET_PATH_PREFIX 423 "[0-9A-F]\\+$", 424 NULL)); 425 } 426 427 /* No other logs */ 428 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 429 EXPECT_EQ(0, records.access); 430 431 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 432 EXPECT_EQ(0, close(dgram_client)); 433 434 ASSERT_EQ(child, waitpid(child, &status, 0)); 435 if (WIFSIGNALED(status) || !WIFEXITED(status) || 436 WEXITSTATUS(status) != EXIT_SUCCESS) 437 _metadata->exit_code = KSFT_FAIL; 438 } 439 440 FIXTURE(scoped_vs_unscoped) 441 { 442 struct service_fixture parent_stream_address, parent_dgram_address, 443 child_stream_address, child_dgram_address; 444 }; 445 446 #include "scoped_multiple_domain_variants.h" 447 448 FIXTURE_SETUP(scoped_vs_unscoped) 449 { 450 drop_caps(_metadata); 451 452 memset(&self->parent_stream_address, 0, 453 sizeof(self->parent_stream_address)); 454 set_unix_address(&self->parent_stream_address, 0); 455 memset(&self->parent_dgram_address, 0, 456 sizeof(self->parent_dgram_address)); 457 set_unix_address(&self->parent_dgram_address, 1); 458 memset(&self->child_stream_address, 0, 459 sizeof(self->child_stream_address)); 460 set_unix_address(&self->child_stream_address, 2); 461 memset(&self->child_dgram_address, 0, 462 sizeof(self->child_dgram_address)); 463 set_unix_address(&self->child_dgram_address, 3); 464 } 465 466 FIXTURE_TEARDOWN(scoped_vs_unscoped) 467 { 468 } 469 470 /* 471 * Test unix_stream_connect and unix_may_send for parent, child and 472 * grand child processes when they can have scoped or non-scoped domains. 473 */ 474 TEST_F(scoped_vs_unscoped, unix_scoping) 475 { 476 pid_t child; 477 int status; 478 bool can_connect_to_parent, can_connect_to_child; 479 int pipe_parent[2]; 480 int stream_server_parent, dgram_server_parent; 481 482 can_connect_to_child = (variant->domain_grand_child != SCOPE_SANDBOX); 483 can_connect_to_parent = (can_connect_to_child && 484 (variant->domain_children != SCOPE_SANDBOX)); 485 486 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 487 488 if (variant->domain_all == OTHER_SANDBOX) 489 create_fs_domain(_metadata); 490 else if (variant->domain_all == SCOPE_SANDBOX) 491 create_scoped_domain(_metadata, 492 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 493 494 child = fork(); 495 ASSERT_LE(0, child); 496 if (child == 0) { 497 int stream_server_child, dgram_server_child; 498 int pipe_child[2]; 499 pid_t grand_child; 500 501 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 502 503 if (variant->domain_children == OTHER_SANDBOX) 504 create_fs_domain(_metadata); 505 else if (variant->domain_children == SCOPE_SANDBOX) 506 create_scoped_domain( 507 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 508 509 grand_child = fork(); 510 ASSERT_LE(0, grand_child); 511 if (grand_child == 0) { 512 char buf; 513 int stream_err, dgram_err, stream_errno, dgram_errno; 514 int stream_client, dgram_client; 515 516 EXPECT_EQ(0, close(pipe_parent[1])); 517 EXPECT_EQ(0, close(pipe_child[1])); 518 519 if (variant->domain_grand_child == OTHER_SANDBOX) 520 create_fs_domain(_metadata); 521 else if (variant->domain_grand_child == SCOPE_SANDBOX) 522 create_scoped_domain( 523 _metadata, 524 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 525 526 stream_client = socket(AF_UNIX, SOCK_STREAM, 0); 527 ASSERT_LE(0, stream_client); 528 dgram_client = socket(AF_UNIX, SOCK_DGRAM, 0); 529 ASSERT_LE(0, dgram_client); 530 531 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 532 stream_err = connect( 533 stream_client, 534 &self->child_stream_address.unix_addr, 535 self->child_stream_address.unix_addr_len); 536 stream_errno = errno; 537 dgram_err = connect( 538 dgram_client, 539 &self->child_dgram_address.unix_addr, 540 self->child_dgram_address.unix_addr_len); 541 dgram_errno = errno; 542 if (can_connect_to_child) { 543 EXPECT_EQ(0, stream_err); 544 EXPECT_EQ(0, dgram_err); 545 } else { 546 EXPECT_EQ(-1, stream_err); 547 EXPECT_EQ(-1, dgram_err); 548 EXPECT_EQ(EPERM, stream_errno); 549 EXPECT_EQ(EPERM, dgram_errno); 550 } 551 552 EXPECT_EQ(0, close(stream_client)); 553 stream_client = socket(AF_UNIX, SOCK_STREAM, 0); 554 ASSERT_LE(0, stream_client); 555 /* Datagram sockets can "reconnect". */ 556 557 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 558 stream_err = connect( 559 stream_client, 560 &self->parent_stream_address.unix_addr, 561 self->parent_stream_address.unix_addr_len); 562 stream_errno = errno; 563 dgram_err = connect( 564 dgram_client, 565 &self->parent_dgram_address.unix_addr, 566 self->parent_dgram_address.unix_addr_len); 567 dgram_errno = errno; 568 if (can_connect_to_parent) { 569 EXPECT_EQ(0, stream_err); 570 EXPECT_EQ(0, dgram_err); 571 } else { 572 EXPECT_EQ(-1, stream_err); 573 EXPECT_EQ(-1, dgram_err); 574 EXPECT_EQ(EPERM, stream_errno); 575 EXPECT_EQ(EPERM, dgram_errno); 576 } 577 EXPECT_EQ(0, close(stream_client)); 578 EXPECT_EQ(0, close(dgram_client)); 579 580 _exit(_metadata->exit_code); 581 return; 582 } 583 EXPECT_EQ(0, close(pipe_child[0])); 584 if (variant->domain_child == OTHER_SANDBOX) 585 create_fs_domain(_metadata); 586 else if (variant->domain_child == SCOPE_SANDBOX) 587 create_scoped_domain( 588 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 589 590 stream_server_child = socket(AF_UNIX, SOCK_STREAM, 0); 591 ASSERT_LE(0, stream_server_child); 592 dgram_server_child = socket(AF_UNIX, SOCK_DGRAM, 0); 593 ASSERT_LE(0, dgram_server_child); 594 595 ASSERT_EQ(0, bind(stream_server_child, 596 &self->child_stream_address.unix_addr, 597 self->child_stream_address.unix_addr_len)); 598 ASSERT_EQ(0, bind(dgram_server_child, 599 &self->child_dgram_address.unix_addr, 600 self->child_dgram_address.unix_addr_len)); 601 ASSERT_EQ(0, listen(stream_server_child, backlog)); 602 603 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 604 ASSERT_EQ(grand_child, waitpid(grand_child, &status, 0)); 605 EXPECT_EQ(0, close(stream_server_child)); 606 EXPECT_EQ(0, close(dgram_server_child)); 607 return; 608 } 609 EXPECT_EQ(0, close(pipe_parent[0])); 610 611 if (variant->domain_parent == OTHER_SANDBOX) 612 create_fs_domain(_metadata); 613 else if (variant->domain_parent == SCOPE_SANDBOX) 614 create_scoped_domain(_metadata, 615 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 616 617 stream_server_parent = socket(AF_UNIX, SOCK_STREAM, 0); 618 ASSERT_LE(0, stream_server_parent); 619 dgram_server_parent = socket(AF_UNIX, SOCK_DGRAM, 0); 620 ASSERT_LE(0, dgram_server_parent); 621 ASSERT_EQ(0, bind(stream_server_parent, 622 &self->parent_stream_address.unix_addr, 623 self->parent_stream_address.unix_addr_len)); 624 ASSERT_EQ(0, bind(dgram_server_parent, 625 &self->parent_dgram_address.unix_addr, 626 self->parent_dgram_address.unix_addr_len)); 627 628 ASSERT_EQ(0, listen(stream_server_parent, backlog)); 629 630 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 631 ASSERT_EQ(child, waitpid(child, &status, 0)); 632 EXPECT_EQ(0, close(stream_server_parent)); 633 EXPECT_EQ(0, close(dgram_server_parent)); 634 635 if (WIFSIGNALED(status) || !WIFEXITED(status) || 636 WEXITSTATUS(status) != EXIT_SUCCESS) 637 _metadata->exit_code = KSFT_FAIL; 638 } 639 640 FIXTURE(outside_socket) 641 { 642 struct service_fixture address, transit_address; 643 }; 644 645 FIXTURE_VARIANT(outside_socket) 646 { 647 const bool child_socket; 648 const int type; 649 }; 650 651 /* clang-format off */ 652 FIXTURE_VARIANT_ADD(outside_socket, allow_dgram_child) { 653 /* clang-format on */ 654 .child_socket = true, 655 .type = SOCK_DGRAM, 656 }; 657 658 /* clang-format off */ 659 FIXTURE_VARIANT_ADD(outside_socket, deny_dgram_server) { 660 /* clang-format on */ 661 .child_socket = false, 662 .type = SOCK_DGRAM, 663 }; 664 665 /* clang-format off */ 666 FIXTURE_VARIANT_ADD(outside_socket, allow_stream_child) { 667 /* clang-format on */ 668 .child_socket = true, 669 .type = SOCK_STREAM, 670 }; 671 672 /* clang-format off */ 673 FIXTURE_VARIANT_ADD(outside_socket, deny_stream_server) { 674 /* clang-format on */ 675 .child_socket = false, 676 .type = SOCK_STREAM, 677 }; 678 679 FIXTURE_SETUP(outside_socket) 680 { 681 drop_caps(_metadata); 682 683 memset(&self->transit_address, 0, sizeof(self->transit_address)); 684 set_unix_address(&self->transit_address, 0); 685 memset(&self->address, 0, sizeof(self->address)); 686 set_unix_address(&self->address, 1); 687 } 688 689 FIXTURE_TEARDOWN(outside_socket) 690 { 691 } 692 693 /* 694 * Test unix_stream_connect and unix_may_send for parent and child processes 695 * when connecting socket has different domain than the process using it. 696 */ 697 TEST_F(outside_socket, socket_with_different_domain) 698 { 699 pid_t child; 700 int err, status; 701 int pipe_child[2], pipe_parent[2]; 702 char buf_parent; 703 int server_socket; 704 705 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 706 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 707 708 child = fork(); 709 ASSERT_LE(0, child); 710 if (child == 0) { 711 int client_socket; 712 char buf_child; 713 714 EXPECT_EQ(0, close(pipe_parent[1])); 715 EXPECT_EQ(0, close(pipe_child[0])); 716 717 /* Client always has a domain. */ 718 create_scoped_domain(_metadata, 719 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 720 721 if (variant->child_socket) { 722 int data_socket, passed_socket, stream_server; 723 724 passed_socket = socket(AF_UNIX, variant->type, 0); 725 ASSERT_LE(0, passed_socket); 726 stream_server = socket(AF_UNIX, SOCK_STREAM, 0); 727 ASSERT_LE(0, stream_server); 728 ASSERT_EQ(0, bind(stream_server, 729 &self->transit_address.unix_addr, 730 self->transit_address.unix_addr_len)); 731 ASSERT_EQ(0, listen(stream_server, backlog)); 732 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 733 data_socket = accept(stream_server, NULL, NULL); 734 ASSERT_LE(0, data_socket); 735 ASSERT_EQ(0, send_fd(data_socket, passed_socket)); 736 EXPECT_EQ(0, close(passed_socket)); 737 EXPECT_EQ(0, close(stream_server)); 738 } 739 740 client_socket = socket(AF_UNIX, variant->type, 0); 741 ASSERT_LE(0, client_socket); 742 743 /* Waits for parent signal for connection. */ 744 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1)); 745 err = connect(client_socket, &self->address.unix_addr, 746 self->address.unix_addr_len); 747 if (variant->child_socket) { 748 EXPECT_EQ(0, err); 749 } else { 750 EXPECT_EQ(-1, err); 751 EXPECT_EQ(EPERM, errno); 752 } 753 EXPECT_EQ(0, close(client_socket)); 754 _exit(_metadata->exit_code); 755 return; 756 } 757 EXPECT_EQ(0, close(pipe_child[1])); 758 EXPECT_EQ(0, close(pipe_parent[0])); 759 760 if (variant->child_socket) { 761 int client_child = socket(AF_UNIX, SOCK_STREAM, 0); 762 763 ASSERT_LE(0, client_child); 764 ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1)); 765 ASSERT_EQ(0, connect(client_child, 766 &self->transit_address.unix_addr, 767 self->transit_address.unix_addr_len)); 768 server_socket = recv_fd(client_child); 769 EXPECT_EQ(0, close(client_child)); 770 } else { 771 server_socket = socket(AF_UNIX, variant->type, 0); 772 } 773 ASSERT_LE(0, server_socket); 774 775 /* Server always has a domain. */ 776 create_scoped_domain(_metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 777 778 ASSERT_EQ(0, bind(server_socket, &self->address.unix_addr, 779 self->address.unix_addr_len)); 780 if (variant->type == SOCK_STREAM) 781 ASSERT_EQ(0, listen(server_socket, backlog)); 782 783 /* Signals to child that the parent is listening. */ 784 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 785 786 ASSERT_EQ(child, waitpid(child, &status, 0)); 787 EXPECT_EQ(0, close(server_socket)); 788 789 if (WIFSIGNALED(status) || !WIFEXITED(status) || 790 WEXITSTATUS(status) != EXIT_SUCCESS) 791 _metadata->exit_code = KSFT_FAIL; 792 } 793 794 static const char stream_path[] = TMP_DIR "/stream.sock"; 795 static const char dgram_path[] = TMP_DIR "/dgram.sock"; 796 797 /* clang-format off */ 798 FIXTURE(various_address_sockets) {}; 799 /* clang-format on */ 800 801 FIXTURE_VARIANT(various_address_sockets) 802 { 803 const int domain; 804 }; 805 806 /* clang-format off */ 807 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_scoped_domain) { 808 /* clang-format on */ 809 .domain = SCOPE_SANDBOX, 810 }; 811 812 /* clang-format off */ 813 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_other_domain) { 814 /* clang-format on */ 815 .domain = OTHER_SANDBOX, 816 }; 817 818 /* clang-format off */ 819 FIXTURE_VARIANT_ADD(various_address_sockets, pathname_socket_no_domain) { 820 /* clang-format on */ 821 .domain = NO_SANDBOX, 822 }; 823 824 FIXTURE_SETUP(various_address_sockets) 825 { 826 drop_caps(_metadata); 827 828 umask(0077); 829 ASSERT_EQ(0, mkdir(TMP_DIR, 0700)); 830 } 831 832 FIXTURE_TEARDOWN(various_address_sockets) 833 { 834 EXPECT_EQ(0, unlink(stream_path)); 835 EXPECT_EQ(0, unlink(dgram_path)); 836 EXPECT_EQ(0, rmdir(TMP_DIR)); 837 } 838 839 TEST_F(various_address_sockets, scoped_pathname_sockets) 840 { 841 pid_t child; 842 int status; 843 char buf_child, buf_parent; 844 int pipe_parent[2]; 845 int unnamed_sockets[2]; 846 int stream_pathname_socket, dgram_pathname_socket, 847 stream_abstract_socket, dgram_abstract_socket, data_socket; 848 struct service_fixture stream_abstract_addr, dgram_abstract_addr; 849 struct sockaddr_un stream_pathname_addr = { 850 .sun_family = AF_UNIX, 851 }; 852 struct sockaddr_un dgram_pathname_addr = { 853 .sun_family = AF_UNIX, 854 }; 855 856 /* Pathname address. */ 857 snprintf(stream_pathname_addr.sun_path, 858 sizeof(stream_pathname_addr.sun_path), "%s", stream_path); 859 snprintf(dgram_pathname_addr.sun_path, 860 sizeof(dgram_pathname_addr.sun_path), "%s", dgram_path); 861 862 /* Abstract address. */ 863 memset(&stream_abstract_addr, 0, sizeof(stream_abstract_addr)); 864 set_unix_address(&stream_abstract_addr, 0); 865 memset(&dgram_abstract_addr, 0, sizeof(dgram_abstract_addr)); 866 set_unix_address(&dgram_abstract_addr, 1); 867 868 /* Unnamed address for datagram socket. */ 869 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_DGRAM, 0, unnamed_sockets)); 870 871 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 872 873 child = fork(); 874 ASSERT_LE(0, child); 875 if (child == 0) { 876 int err; 877 878 EXPECT_EQ(0, close(pipe_parent[1])); 879 EXPECT_EQ(0, close(unnamed_sockets[1])); 880 881 if (variant->domain == SCOPE_SANDBOX) 882 create_scoped_domain( 883 _metadata, LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 884 else if (variant->domain == OTHER_SANDBOX) 885 create_fs_domain(_metadata); 886 887 /* Waits for parent to listen. */ 888 ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1)); 889 EXPECT_EQ(0, close(pipe_parent[0])); 890 891 /* Checks that we can send data through a datagram socket. */ 892 ASSERT_EQ(1, write(unnamed_sockets[0], "a", 1)); 893 EXPECT_EQ(0, close(unnamed_sockets[0])); 894 895 /* Connects with pathname sockets. */ 896 stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0); 897 ASSERT_LE(0, stream_pathname_socket); 898 ASSERT_EQ(0, 899 connect(stream_pathname_socket, &stream_pathname_addr, 900 sizeof(stream_pathname_addr))); 901 ASSERT_EQ(1, write(stream_pathname_socket, "b", 1)); 902 EXPECT_EQ(0, close(stream_pathname_socket)); 903 904 /* Sends without connection. */ 905 dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 906 ASSERT_LE(0, dgram_pathname_socket); 907 err = sendto(dgram_pathname_socket, "c", 1, 0, 908 &dgram_pathname_addr, sizeof(dgram_pathname_addr)); 909 EXPECT_EQ(1, err); 910 911 /* Sends with connection. */ 912 ASSERT_EQ(0, 913 connect(dgram_pathname_socket, &dgram_pathname_addr, 914 sizeof(dgram_pathname_addr))); 915 ASSERT_EQ(1, write(dgram_pathname_socket, "d", 1)); 916 EXPECT_EQ(0, close(dgram_pathname_socket)); 917 918 /* Connects with abstract sockets. */ 919 stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0); 920 ASSERT_LE(0, stream_abstract_socket); 921 err = connect(stream_abstract_socket, 922 &stream_abstract_addr.unix_addr, 923 stream_abstract_addr.unix_addr_len); 924 if (variant->domain == SCOPE_SANDBOX) { 925 EXPECT_EQ(-1, err); 926 EXPECT_EQ(EPERM, errno); 927 } else { 928 EXPECT_EQ(0, err); 929 ASSERT_EQ(1, write(stream_abstract_socket, "e", 1)); 930 } 931 EXPECT_EQ(0, close(stream_abstract_socket)); 932 933 /* Sends without connection. */ 934 dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 935 ASSERT_LE(0, dgram_abstract_socket); 936 err = sendto(dgram_abstract_socket, "f", 1, 0, 937 &dgram_abstract_addr.unix_addr, 938 dgram_abstract_addr.unix_addr_len); 939 if (variant->domain == SCOPE_SANDBOX) { 940 EXPECT_EQ(-1, err); 941 EXPECT_EQ(EPERM, errno); 942 } else { 943 EXPECT_EQ(1, err); 944 } 945 946 /* Sends with connection. */ 947 err = connect(dgram_abstract_socket, 948 &dgram_abstract_addr.unix_addr, 949 dgram_abstract_addr.unix_addr_len); 950 if (variant->domain == SCOPE_SANDBOX) { 951 EXPECT_EQ(-1, err); 952 EXPECT_EQ(EPERM, errno); 953 } else { 954 EXPECT_EQ(0, err); 955 ASSERT_EQ(1, write(dgram_abstract_socket, "g", 1)); 956 } 957 EXPECT_EQ(0, close(dgram_abstract_socket)); 958 959 _exit(_metadata->exit_code); 960 return; 961 } 962 EXPECT_EQ(0, close(pipe_parent[0])); 963 EXPECT_EQ(0, close(unnamed_sockets[0])); 964 965 /* Sets up pathname servers. */ 966 stream_pathname_socket = socket(AF_UNIX, SOCK_STREAM, 0); 967 ASSERT_LE(0, stream_pathname_socket); 968 ASSERT_EQ(0, bind(stream_pathname_socket, &stream_pathname_addr, 969 sizeof(stream_pathname_addr))); 970 ASSERT_EQ(0, listen(stream_pathname_socket, backlog)); 971 972 dgram_pathname_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 973 ASSERT_LE(0, dgram_pathname_socket); 974 ASSERT_EQ(0, bind(dgram_pathname_socket, &dgram_pathname_addr, 975 sizeof(dgram_pathname_addr))); 976 977 /* Sets up abstract servers. */ 978 stream_abstract_socket = socket(AF_UNIX, SOCK_STREAM, 0); 979 ASSERT_LE(0, stream_abstract_socket); 980 ASSERT_EQ(0, 981 bind(stream_abstract_socket, &stream_abstract_addr.unix_addr, 982 stream_abstract_addr.unix_addr_len)); 983 984 dgram_abstract_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 985 ASSERT_LE(0, dgram_abstract_socket); 986 ASSERT_EQ(0, bind(dgram_abstract_socket, &dgram_abstract_addr.unix_addr, 987 dgram_abstract_addr.unix_addr_len)); 988 ASSERT_EQ(0, listen(stream_abstract_socket, backlog)); 989 990 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 991 EXPECT_EQ(0, close(pipe_parent[1])); 992 993 /* Reads from unnamed socket. */ 994 ASSERT_EQ(1, read(unnamed_sockets[1], &buf_parent, sizeof(buf_parent))); 995 ASSERT_EQ('a', buf_parent); 996 EXPECT_LE(0, close(unnamed_sockets[1])); 997 998 /* Reads from pathname sockets. */ 999 data_socket = accept(stream_pathname_socket, NULL, NULL); 1000 ASSERT_LE(0, data_socket); 1001 ASSERT_EQ(1, read(data_socket, &buf_parent, sizeof(buf_parent))); 1002 ASSERT_EQ('b', buf_parent); 1003 EXPECT_EQ(0, close(data_socket)); 1004 EXPECT_EQ(0, close(stream_pathname_socket)); 1005 1006 ASSERT_EQ(1, 1007 read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent))); 1008 ASSERT_EQ('c', buf_parent); 1009 ASSERT_EQ(1, 1010 read(dgram_pathname_socket, &buf_parent, sizeof(buf_parent))); 1011 ASSERT_EQ('d', buf_parent); 1012 EXPECT_EQ(0, close(dgram_pathname_socket)); 1013 1014 if (variant->domain != SCOPE_SANDBOX) { 1015 /* Reads from abstract sockets if allowed to send. */ 1016 data_socket = accept(stream_abstract_socket, NULL, NULL); 1017 ASSERT_LE(0, data_socket); 1018 ASSERT_EQ(1, 1019 read(data_socket, &buf_parent, sizeof(buf_parent))); 1020 ASSERT_EQ('e', buf_parent); 1021 EXPECT_EQ(0, close(data_socket)); 1022 1023 ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent, 1024 sizeof(buf_parent))); 1025 ASSERT_EQ('f', buf_parent); 1026 ASSERT_EQ(1, read(dgram_abstract_socket, &buf_parent, 1027 sizeof(buf_parent))); 1028 ASSERT_EQ('g', buf_parent); 1029 } 1030 1031 /* Waits for all abstract socket tests. */ 1032 ASSERT_EQ(child, waitpid(child, &status, 0)); 1033 EXPECT_EQ(0, close(stream_abstract_socket)); 1034 EXPECT_EQ(0, close(dgram_abstract_socket)); 1035 1036 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1037 WEXITSTATUS(status) != EXIT_SUCCESS) 1038 _metadata->exit_code = KSFT_FAIL; 1039 } 1040 1041 TEST(datagram_sockets) 1042 { 1043 struct service_fixture connected_addr, non_connected_addr; 1044 int server_conn_socket, server_unconn_socket; 1045 int pipe_parent[2], pipe_child[2]; 1046 int status; 1047 char buf; 1048 pid_t child; 1049 1050 drop_caps(_metadata); 1051 memset(&connected_addr, 0, sizeof(connected_addr)); 1052 set_unix_address(&connected_addr, 0); 1053 memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 1054 set_unix_address(&non_connected_addr, 1); 1055 1056 ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC)); 1057 ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC)); 1058 1059 child = fork(); 1060 ASSERT_LE(0, child); 1061 if (child == 0) { 1062 int client_conn_socket, client_unconn_socket; 1063 1064 EXPECT_EQ(0, close(pipe_parent[1])); 1065 EXPECT_EQ(0, close(pipe_child[0])); 1066 1067 client_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1068 client_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1069 ASSERT_LE(0, client_conn_socket); 1070 ASSERT_LE(0, client_unconn_socket); 1071 1072 /* Waits for parent to listen. */ 1073 ASSERT_EQ(1, read(pipe_parent[0], &buf, 1)); 1074 ASSERT_EQ(0, 1075 connect(client_conn_socket, &connected_addr.unix_addr, 1076 connected_addr.unix_addr_len)); 1077 1078 /* 1079 * Both connected and non-connected sockets can send data when 1080 * the domain is not scoped. 1081 */ 1082 ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0)); 1083 ASSERT_EQ(1, sendto(client_unconn_socket, ".", 1, 0, 1084 &non_connected_addr.unix_addr, 1085 non_connected_addr.unix_addr_len)); 1086 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 1087 1088 /* Scopes the domain. */ 1089 create_scoped_domain(_metadata, 1090 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1091 1092 /* 1093 * Connected socket sends data to the receiver, but the 1094 * non-connected socket must fail to send data. 1095 */ 1096 ASSERT_EQ(1, send(client_conn_socket, ".", 1, 0)); 1097 ASSERT_EQ(-1, sendto(client_unconn_socket, ".", 1, 0, 1098 &non_connected_addr.unix_addr, 1099 non_connected_addr.unix_addr_len)); 1100 ASSERT_EQ(EPERM, errno); 1101 ASSERT_EQ(1, write(pipe_child[1], ".", 1)); 1102 1103 EXPECT_EQ(0, close(client_conn_socket)); 1104 EXPECT_EQ(0, close(client_unconn_socket)); 1105 _exit(_metadata->exit_code); 1106 return; 1107 } 1108 EXPECT_EQ(0, close(pipe_parent[0])); 1109 EXPECT_EQ(0, close(pipe_child[1])); 1110 1111 server_conn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1112 server_unconn_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1113 ASSERT_LE(0, server_conn_socket); 1114 ASSERT_LE(0, server_unconn_socket); 1115 1116 ASSERT_EQ(0, bind(server_conn_socket, &connected_addr.unix_addr, 1117 connected_addr.unix_addr_len)); 1118 ASSERT_EQ(0, bind(server_unconn_socket, &non_connected_addr.unix_addr, 1119 non_connected_addr.unix_addr_len)); 1120 ASSERT_EQ(1, write(pipe_parent[1], ".", 1)); 1121 1122 /* Waits for child to test. */ 1123 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 1124 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0)); 1125 ASSERT_EQ(1, recv(server_unconn_socket, &buf, 1, 0)); 1126 1127 /* 1128 * Connected datagram socket will receive data, but 1129 * non-connected datagram socket does not receive data. 1130 */ 1131 ASSERT_EQ(1, read(pipe_child[0], &buf, 1)); 1132 ASSERT_EQ(1, recv(server_conn_socket, &buf, 1, 0)); 1133 1134 /* Waits for all tests to finish. */ 1135 ASSERT_EQ(child, waitpid(child, &status, 0)); 1136 EXPECT_EQ(0, close(server_conn_socket)); 1137 EXPECT_EQ(0, close(server_unconn_socket)); 1138 1139 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1140 WEXITSTATUS(status) != EXIT_SUCCESS) 1141 _metadata->exit_code = KSFT_FAIL; 1142 } 1143 1144 TEST(self_connect) 1145 { 1146 struct service_fixture connected_addr, non_connected_addr; 1147 int connected_socket, non_connected_socket, status; 1148 pid_t child; 1149 1150 drop_caps(_metadata); 1151 memset(&connected_addr, 0, sizeof(connected_addr)); 1152 set_unix_address(&connected_addr, 0); 1153 memset(&non_connected_addr, 0, sizeof(non_connected_addr)); 1154 set_unix_address(&non_connected_addr, 1); 1155 1156 connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1157 non_connected_socket = socket(AF_UNIX, SOCK_DGRAM, 0); 1158 ASSERT_LE(0, connected_socket); 1159 ASSERT_LE(0, non_connected_socket); 1160 1161 ASSERT_EQ(0, bind(connected_socket, &connected_addr.unix_addr, 1162 connected_addr.unix_addr_len)); 1163 ASSERT_EQ(0, bind(non_connected_socket, &non_connected_addr.unix_addr, 1164 non_connected_addr.unix_addr_len)); 1165 1166 child = fork(); 1167 ASSERT_LE(0, child); 1168 if (child == 0) { 1169 /* Child's domain is scoped. */ 1170 create_scoped_domain(_metadata, 1171 LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET); 1172 1173 /* 1174 * The child inherits the sockets, and cannot connect or 1175 * send data to them. 1176 */ 1177 ASSERT_EQ(-1, 1178 connect(connected_socket, &connected_addr.unix_addr, 1179 connected_addr.unix_addr_len)); 1180 ASSERT_EQ(EPERM, errno); 1181 1182 ASSERT_EQ(-1, sendto(connected_socket, ".", 1, 0, 1183 &connected_addr.unix_addr, 1184 connected_addr.unix_addr_len)); 1185 ASSERT_EQ(EPERM, errno); 1186 1187 ASSERT_EQ(-1, sendto(non_connected_socket, ".", 1, 0, 1188 &non_connected_addr.unix_addr, 1189 non_connected_addr.unix_addr_len)); 1190 ASSERT_EQ(EPERM, errno); 1191 1192 EXPECT_EQ(0, close(connected_socket)); 1193 EXPECT_EQ(0, close(non_connected_socket)); 1194 _exit(_metadata->exit_code); 1195 return; 1196 } 1197 1198 /* Waits for all tests to finish. */ 1199 ASSERT_EQ(child, waitpid(child, &status, 0)); 1200 EXPECT_EQ(0, close(connected_socket)); 1201 EXPECT_EQ(0, close(non_connected_socket)); 1202 1203 if (WIFSIGNALED(status) || !WIFEXITED(status) || 1204 WEXITSTATUS(status) != EXIT_SUCCESS) 1205 _metadata->exit_code = KSFT_FAIL; 1206 } 1207 1208 TEST_HARNESS_MAIN 1209