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