1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Landlock tests - Network 4 * 5 * Copyright © 2022-2023 Huawei Tech. Co., Ltd. 6 * Copyright © 2023 Microsoft Corporation 7 */ 8 9 #define _GNU_SOURCE 10 #include <arpa/inet.h> 11 #include <errno.h> 12 #include <fcntl.h> 13 #include <linux/landlock.h> 14 #include <linux/in.h> 15 #include <sched.h> 16 #include <stdint.h> 17 #include <string.h> 18 #include <sys/prctl.h> 19 #include <sys/socket.h> 20 #include <sys/syscall.h> 21 #include <sys/un.h> 22 23 #include "audit.h" 24 #include "common.h" 25 26 const short sock_port_start = (1 << 10); 27 28 static const char loopback_ipv4[] = "127.0.0.1"; 29 static const char loopback_ipv6[] = "::1"; 30 31 /* Number pending connections queue to be hold. */ 32 const short backlog = 10; 33 34 enum sandbox_type { 35 NO_SANDBOX, 36 /* This may be used to test rules that allow *and* deny accesses. */ 37 TCP_SANDBOX, 38 }; 39 40 static int set_service(struct service_fixture *const srv, 41 const struct protocol_variant prot, 42 const unsigned short index) 43 { 44 memset(srv, 0, sizeof(*srv)); 45 46 /* 47 * Copies all protocol properties in case of the variant only contains 48 * a subset of them. 49 */ 50 srv->protocol = prot; 51 52 /* Checks for port overflow. */ 53 if (index > 2) 54 return 1; 55 srv->port = sock_port_start << (2 * index); 56 57 switch (prot.domain) { 58 case AF_UNSPEC: 59 case AF_INET: 60 srv->ipv4_addr.sin_family = prot.domain; 61 srv->ipv4_addr.sin_port = htons(srv->port); 62 srv->ipv4_addr.sin_addr.s_addr = inet_addr(loopback_ipv4); 63 return 0; 64 65 case AF_INET6: 66 srv->ipv6_addr.sin6_family = prot.domain; 67 srv->ipv6_addr.sin6_port = htons(srv->port); 68 inet_pton(AF_INET6, loopback_ipv6, &srv->ipv6_addr.sin6_addr); 69 return 0; 70 71 case AF_UNIX: 72 set_unix_address(srv, index); 73 return 0; 74 } 75 return 1; 76 } 77 78 static void setup_loopback(struct __test_metadata *const _metadata) 79 { 80 set_cap(_metadata, CAP_SYS_ADMIN); 81 ASSERT_EQ(0, unshare(CLONE_NEWNET)); 82 clear_cap(_metadata, CAP_SYS_ADMIN); 83 84 set_ambient_cap(_metadata, CAP_NET_ADMIN); 85 ASSERT_EQ(0, system("ip link set dev lo up")); 86 clear_ambient_cap(_metadata, CAP_NET_ADMIN); 87 } 88 89 static bool prot_is_tcp(const struct protocol_variant *const prot) 90 { 91 return (prot->domain == AF_INET || prot->domain == AF_INET6) && 92 prot->type == SOCK_STREAM && 93 (prot->protocol == IPPROTO_TCP || prot->protocol == IPPROTO_IP); 94 } 95 96 static bool is_restricted(const struct protocol_variant *const prot, 97 const enum sandbox_type sandbox) 98 { 99 if (sandbox == TCP_SANDBOX) 100 return prot_is_tcp(prot); 101 return false; 102 } 103 104 static int socket_variant(const struct service_fixture *const srv) 105 { 106 int ret; 107 108 ret = socket(srv->protocol.domain, srv->protocol.type | SOCK_CLOEXEC, 109 srv->protocol.protocol); 110 if (ret < 0) 111 return -errno; 112 return ret; 113 } 114 115 #ifndef SIN6_LEN_RFC2133 116 #define SIN6_LEN_RFC2133 24 117 #endif 118 119 static socklen_t get_addrlen(const struct service_fixture *const srv, 120 const bool minimal) 121 { 122 switch (srv->protocol.domain) { 123 case AF_UNSPEC: 124 if (minimal) 125 return sizeof(sa_family_t); 126 return sizeof(struct sockaddr_storage); 127 128 case AF_INET: 129 return sizeof(srv->ipv4_addr); 130 131 case AF_INET6: 132 if (minimal) 133 return SIN6_LEN_RFC2133; 134 return sizeof(srv->ipv6_addr); 135 136 case AF_UNIX: 137 if (minimal) 138 return sizeof(srv->unix_addr) - 139 sizeof(srv->unix_addr.sun_path); 140 return srv->unix_addr_len; 141 142 default: 143 return 0; 144 } 145 } 146 147 static void set_port(struct service_fixture *const srv, uint16_t port) 148 { 149 switch (srv->protocol.domain) { 150 case AF_UNSPEC: 151 case AF_INET: 152 srv->ipv4_addr.sin_port = htons(port); 153 return; 154 155 case AF_INET6: 156 srv->ipv6_addr.sin6_port = htons(port); 157 return; 158 159 default: 160 return; 161 } 162 } 163 164 static uint16_t get_binded_port(int socket_fd, 165 const struct protocol_variant *const prot) 166 { 167 struct sockaddr_in ipv4_addr; 168 struct sockaddr_in6 ipv6_addr; 169 socklen_t ipv4_addr_len, ipv6_addr_len; 170 171 /* Gets binded port. */ 172 switch (prot->domain) { 173 case AF_UNSPEC: 174 case AF_INET: 175 ipv4_addr_len = sizeof(ipv4_addr); 176 getsockname(socket_fd, &ipv4_addr, &ipv4_addr_len); 177 return ntohs(ipv4_addr.sin_port); 178 179 case AF_INET6: 180 ipv6_addr_len = sizeof(ipv6_addr); 181 getsockname(socket_fd, &ipv6_addr, &ipv6_addr_len); 182 return ntohs(ipv6_addr.sin6_port); 183 184 default: 185 return 0; 186 } 187 } 188 189 static int bind_variant_addrlen(const int sock_fd, 190 const struct service_fixture *const srv, 191 const socklen_t addrlen) 192 { 193 int ret; 194 195 switch (srv->protocol.domain) { 196 case AF_UNSPEC: 197 case AF_INET: 198 ret = bind(sock_fd, &srv->ipv4_addr, addrlen); 199 break; 200 201 case AF_INET6: 202 ret = bind(sock_fd, &srv->ipv6_addr, addrlen); 203 break; 204 205 case AF_UNIX: 206 ret = bind(sock_fd, &srv->unix_addr, addrlen); 207 break; 208 209 default: 210 errno = EAFNOSUPPORT; 211 return -errno; 212 } 213 214 if (ret < 0) 215 return -errno; 216 return ret; 217 } 218 219 static int bind_variant(const int sock_fd, 220 const struct service_fixture *const srv) 221 { 222 return bind_variant_addrlen(sock_fd, srv, get_addrlen(srv, false)); 223 } 224 225 static int connect_variant_addrlen(const int sock_fd, 226 const struct service_fixture *const srv, 227 const socklen_t addrlen) 228 { 229 int ret; 230 231 switch (srv->protocol.domain) { 232 case AF_UNSPEC: 233 case AF_INET: 234 ret = connect(sock_fd, &srv->ipv4_addr, addrlen); 235 break; 236 237 case AF_INET6: 238 ret = connect(sock_fd, &srv->ipv6_addr, addrlen); 239 break; 240 241 case AF_UNIX: 242 ret = connect(sock_fd, &srv->unix_addr, addrlen); 243 break; 244 245 default: 246 errno = -EAFNOSUPPORT; 247 return -errno; 248 } 249 250 if (ret < 0) 251 return -errno; 252 return ret; 253 } 254 255 static int connect_variant(const int sock_fd, 256 const struct service_fixture *const srv) 257 { 258 return connect_variant_addrlen(sock_fd, srv, get_addrlen(srv, false)); 259 } 260 261 FIXTURE(protocol) 262 { 263 struct service_fixture srv0, srv1, srv2, unspec_any0, unspec_srv0; 264 }; 265 266 FIXTURE_VARIANT(protocol) 267 { 268 const enum sandbox_type sandbox; 269 const struct protocol_variant prot; 270 }; 271 272 FIXTURE_SETUP(protocol) 273 { 274 const struct protocol_variant prot_unspec = { 275 .domain = AF_UNSPEC, 276 .type = SOCK_STREAM, 277 }; 278 279 disable_caps(_metadata); 280 281 ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0)); 282 ASSERT_EQ(0, set_service(&self->srv1, variant->prot, 1)); 283 ASSERT_EQ(0, set_service(&self->srv2, variant->prot, 2)); 284 285 ASSERT_EQ(0, set_service(&self->unspec_srv0, prot_unspec, 0)); 286 287 ASSERT_EQ(0, set_service(&self->unspec_any0, prot_unspec, 0)); 288 self->unspec_any0.ipv4_addr.sin_addr.s_addr = htonl(INADDR_ANY); 289 290 setup_loopback(_metadata); 291 }; 292 293 FIXTURE_TEARDOWN(protocol) 294 { 295 } 296 297 /* clang-format off */ 298 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp1) { 299 /* clang-format on */ 300 .sandbox = NO_SANDBOX, 301 .prot = { 302 .domain = AF_INET, 303 .type = SOCK_STREAM, 304 /* IPPROTO_IP == 0 */ 305 .protocol = IPPROTO_IP, 306 }, 307 }; 308 309 /* clang-format off */ 310 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_tcp2) { 311 /* clang-format on */ 312 .sandbox = NO_SANDBOX, 313 .prot = { 314 .domain = AF_INET, 315 .type = SOCK_STREAM, 316 .protocol = IPPROTO_TCP, 317 }, 318 }; 319 320 /* clang-format off */ 321 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_mptcp) { 322 /* clang-format on */ 323 .sandbox = NO_SANDBOX, 324 .prot = { 325 .domain = AF_INET, 326 .type = SOCK_STREAM, 327 .protocol = IPPROTO_MPTCP, 328 }, 329 }; 330 331 /* clang-format off */ 332 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp1) { 333 /* clang-format on */ 334 .sandbox = NO_SANDBOX, 335 .prot = { 336 .domain = AF_INET6, 337 .type = SOCK_STREAM, 338 /* IPPROTO_IP == 0 */ 339 .protocol = IPPROTO_IP, 340 }, 341 }; 342 343 /* clang-format off */ 344 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_tcp2) { 345 /* clang-format on */ 346 .sandbox = NO_SANDBOX, 347 .prot = { 348 .domain = AF_INET6, 349 .type = SOCK_STREAM, 350 .protocol = IPPROTO_TCP, 351 }, 352 }; 353 354 /* clang-format off */ 355 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_mptcp) { 356 /* clang-format on */ 357 .sandbox = NO_SANDBOX, 358 .prot = { 359 .domain = AF_INET6, 360 .type = SOCK_STREAM, 361 .protocol = IPPROTO_MPTCP, 362 }, 363 }; 364 365 /* clang-format off */ 366 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv4_udp) { 367 /* clang-format on */ 368 .sandbox = NO_SANDBOX, 369 .prot = { 370 .domain = AF_INET, 371 .type = SOCK_DGRAM, 372 }, 373 }; 374 375 /* clang-format off */ 376 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_ipv6_udp) { 377 /* clang-format on */ 378 .sandbox = NO_SANDBOX, 379 .prot = { 380 .domain = AF_INET6, 381 .type = SOCK_DGRAM, 382 }, 383 }; 384 385 /* clang-format off */ 386 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_unix_stream) { 387 /* clang-format on */ 388 .sandbox = NO_SANDBOX, 389 .prot = { 390 .domain = AF_UNIX, 391 .type = SOCK_STREAM, 392 }, 393 }; 394 395 /* clang-format off */ 396 FIXTURE_VARIANT_ADD(protocol, no_sandbox_with_unix_datagram) { 397 /* clang-format on */ 398 .sandbox = NO_SANDBOX, 399 .prot = { 400 .domain = AF_UNIX, 401 .type = SOCK_DGRAM, 402 }, 403 }; 404 405 /* clang-format off */ 406 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp1) { 407 /* clang-format on */ 408 .sandbox = TCP_SANDBOX, 409 .prot = { 410 .domain = AF_INET, 411 .type = SOCK_STREAM, 412 /* IPPROTO_IP == 0 */ 413 .protocol = IPPROTO_IP, 414 }, 415 }; 416 417 /* clang-format off */ 418 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_tcp2) { 419 /* clang-format on */ 420 .sandbox = TCP_SANDBOX, 421 .prot = { 422 .domain = AF_INET, 423 .type = SOCK_STREAM, 424 .protocol = IPPROTO_TCP, 425 }, 426 }; 427 428 /* clang-format off */ 429 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_mptcp) { 430 /* clang-format on */ 431 .sandbox = TCP_SANDBOX, 432 .prot = { 433 .domain = AF_INET, 434 .type = SOCK_STREAM, 435 .protocol = IPPROTO_MPTCP, 436 }, 437 }; 438 439 /* clang-format off */ 440 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp1) { 441 /* clang-format on */ 442 .sandbox = TCP_SANDBOX, 443 .prot = { 444 .domain = AF_INET6, 445 .type = SOCK_STREAM, 446 /* IPPROTO_IP == 0 */ 447 .protocol = IPPROTO_IP, 448 }, 449 }; 450 451 /* clang-format off */ 452 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_tcp2) { 453 /* clang-format on */ 454 .sandbox = TCP_SANDBOX, 455 .prot = { 456 .domain = AF_INET6, 457 .type = SOCK_STREAM, 458 .protocol = IPPROTO_TCP, 459 }, 460 }; 461 462 /* clang-format off */ 463 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_mptcp) { 464 /* clang-format on */ 465 .sandbox = TCP_SANDBOX, 466 .prot = { 467 .domain = AF_INET6, 468 .type = SOCK_STREAM, 469 .protocol = IPPROTO_MPTCP, 470 }, 471 }; 472 473 /* clang-format off */ 474 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv4_udp) { 475 /* clang-format on */ 476 .sandbox = TCP_SANDBOX, 477 .prot = { 478 .domain = AF_INET, 479 .type = SOCK_DGRAM, 480 }, 481 }; 482 483 /* clang-format off */ 484 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_ipv6_udp) { 485 /* clang-format on */ 486 .sandbox = TCP_SANDBOX, 487 .prot = { 488 .domain = AF_INET6, 489 .type = SOCK_DGRAM, 490 }, 491 }; 492 493 /* clang-format off */ 494 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_unix_stream) { 495 /* clang-format on */ 496 .sandbox = TCP_SANDBOX, 497 .prot = { 498 .domain = AF_UNIX, 499 .type = SOCK_STREAM, 500 }, 501 }; 502 503 /* clang-format off */ 504 FIXTURE_VARIANT_ADD(protocol, tcp_sandbox_with_unix_datagram) { 505 /* clang-format on */ 506 .sandbox = TCP_SANDBOX, 507 .prot = { 508 .domain = AF_UNIX, 509 .type = SOCK_DGRAM, 510 }, 511 }; 512 513 static void test_bind_and_connect(struct __test_metadata *const _metadata, 514 const struct service_fixture *const srv, 515 const bool deny_bind, const bool deny_connect) 516 { 517 char buf = '\0'; 518 int inval_fd, bind_fd, client_fd, status, ret; 519 pid_t child; 520 521 /* Starts invalid addrlen tests with bind. */ 522 inval_fd = socket_variant(srv); 523 ASSERT_LE(0, inval_fd) 524 { 525 TH_LOG("Failed to create socket: %s", strerror(errno)); 526 } 527 528 /* Tries to bind with zero as addrlen. */ 529 EXPECT_EQ(-EINVAL, bind_variant_addrlen(inval_fd, srv, 0)); 530 531 /* Tries to bind with too small addrlen. */ 532 EXPECT_EQ(-EINVAL, bind_variant_addrlen(inval_fd, srv, 533 get_addrlen(srv, true) - 1)); 534 535 /* Tries to bind with minimal addrlen. */ 536 ret = bind_variant_addrlen(inval_fd, srv, get_addrlen(srv, true)); 537 if (deny_bind) { 538 EXPECT_EQ(-EACCES, ret); 539 } else { 540 EXPECT_EQ(0, ret) 541 { 542 TH_LOG("Failed to bind to socket: %s", strerror(errno)); 543 } 544 } 545 EXPECT_EQ(0, close(inval_fd)); 546 547 /* Starts invalid addrlen tests with connect. */ 548 inval_fd = socket_variant(srv); 549 ASSERT_LE(0, inval_fd); 550 551 /* Tries to connect with zero as addrlen. */ 552 EXPECT_EQ(-EINVAL, connect_variant_addrlen(inval_fd, srv, 0)); 553 554 /* Tries to connect with too small addrlen. */ 555 EXPECT_EQ(-EINVAL, connect_variant_addrlen(inval_fd, srv, 556 get_addrlen(srv, true) - 1)); 557 558 /* Tries to connect with minimal addrlen. */ 559 ret = connect_variant_addrlen(inval_fd, srv, get_addrlen(srv, true)); 560 if (srv->protocol.domain == AF_UNIX) { 561 EXPECT_EQ(-EINVAL, ret); 562 } else if (deny_connect) { 563 EXPECT_EQ(-EACCES, ret); 564 } else if (srv->protocol.type == SOCK_STREAM) { 565 /* No listening server, whatever the value of deny_bind. */ 566 EXPECT_EQ(-ECONNREFUSED, ret); 567 } else { 568 EXPECT_EQ(0, ret) 569 { 570 TH_LOG("Failed to connect to socket: %s", 571 strerror(errno)); 572 } 573 } 574 EXPECT_EQ(0, close(inval_fd)); 575 576 /* Starts connection tests. */ 577 bind_fd = socket_variant(srv); 578 ASSERT_LE(0, bind_fd); 579 580 ret = bind_variant(bind_fd, srv); 581 if (deny_bind) { 582 EXPECT_EQ(-EACCES, ret); 583 } else { 584 EXPECT_EQ(0, ret); 585 586 /* Creates a listening socket. */ 587 if (srv->protocol.type == SOCK_STREAM) 588 EXPECT_EQ(0, listen(bind_fd, backlog)); 589 } 590 591 child = fork(); 592 ASSERT_LE(0, child); 593 if (child == 0) { 594 int connect_fd, ret; 595 596 /* Closes listening socket for the child. */ 597 EXPECT_EQ(0, close(bind_fd)); 598 599 /* Starts connection tests. */ 600 connect_fd = socket_variant(srv); 601 ASSERT_LE(0, connect_fd); 602 ret = connect_variant(connect_fd, srv); 603 if (deny_connect) { 604 EXPECT_EQ(-EACCES, ret); 605 } else if (deny_bind) { 606 /* No listening server. */ 607 EXPECT_EQ(-ECONNREFUSED, ret); 608 } else { 609 EXPECT_EQ(0, ret); 610 EXPECT_EQ(1, write(connect_fd, ".", 1)); 611 } 612 613 EXPECT_EQ(0, close(connect_fd)); 614 _exit(_metadata->exit_code); 615 return; 616 } 617 618 /* Accepts connection from the child. */ 619 client_fd = bind_fd; 620 if (!deny_bind && !deny_connect) { 621 if (srv->protocol.type == SOCK_STREAM) { 622 client_fd = accept(bind_fd, NULL, 0); 623 ASSERT_LE(0, client_fd); 624 } 625 626 EXPECT_EQ(1, read(client_fd, &buf, 1)); 627 EXPECT_EQ('.', buf); 628 } 629 630 EXPECT_EQ(child, waitpid(child, &status, 0)); 631 EXPECT_EQ(1, WIFEXITED(status)); 632 EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 633 634 /* Closes connection, if any. */ 635 if (client_fd != bind_fd) 636 EXPECT_LE(0, close(client_fd)); 637 638 /* Closes listening socket. */ 639 EXPECT_EQ(0, close(bind_fd)); 640 } 641 642 TEST_F(protocol, bind) 643 { 644 if (variant->sandbox == TCP_SANDBOX) { 645 const struct landlock_ruleset_attr ruleset_attr = { 646 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 647 LANDLOCK_ACCESS_NET_CONNECT_TCP, 648 }; 649 const struct landlock_net_port_attr tcp_bind_connect_p0 = { 650 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 651 LANDLOCK_ACCESS_NET_CONNECT_TCP, 652 .port = self->srv0.port, 653 }; 654 const struct landlock_net_port_attr tcp_connect_p1 = { 655 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP, 656 .port = self->srv1.port, 657 }; 658 int ruleset_fd; 659 660 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 661 sizeof(ruleset_attr), 0); 662 ASSERT_LE(0, ruleset_fd); 663 664 /* Allows connect and bind for the first port. */ 665 ASSERT_EQ(0, 666 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 667 &tcp_bind_connect_p0, 0)); 668 669 /* Allows connect and denies bind for the second port. */ 670 ASSERT_EQ(0, 671 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 672 &tcp_connect_p1, 0)); 673 674 enforce_ruleset(_metadata, ruleset_fd); 675 EXPECT_EQ(0, close(ruleset_fd)); 676 } 677 678 /* Binds a socket to the first port. */ 679 test_bind_and_connect(_metadata, &self->srv0, false, false); 680 681 /* Binds a socket to the second port. */ 682 test_bind_and_connect(_metadata, &self->srv1, 683 is_restricted(&variant->prot, variant->sandbox), 684 false); 685 686 /* Binds a socket to the third port. */ 687 test_bind_and_connect(_metadata, &self->srv2, 688 is_restricted(&variant->prot, variant->sandbox), 689 is_restricted(&variant->prot, variant->sandbox)); 690 } 691 692 TEST_F(protocol, connect) 693 { 694 if (variant->sandbox == TCP_SANDBOX) { 695 const struct landlock_ruleset_attr ruleset_attr = { 696 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 697 LANDLOCK_ACCESS_NET_CONNECT_TCP, 698 }; 699 const struct landlock_net_port_attr tcp_bind_connect_p0 = { 700 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 701 LANDLOCK_ACCESS_NET_CONNECT_TCP, 702 .port = self->srv0.port, 703 }; 704 const struct landlock_net_port_attr tcp_bind_p1 = { 705 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 706 .port = self->srv1.port, 707 }; 708 int ruleset_fd; 709 710 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 711 sizeof(ruleset_attr), 0); 712 ASSERT_LE(0, ruleset_fd); 713 714 /* Allows connect and bind for the first port. */ 715 ASSERT_EQ(0, 716 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 717 &tcp_bind_connect_p0, 0)); 718 719 /* Allows bind and denies connect for the second port. */ 720 ASSERT_EQ(0, 721 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 722 &tcp_bind_p1, 0)); 723 724 enforce_ruleset(_metadata, ruleset_fd); 725 EXPECT_EQ(0, close(ruleset_fd)); 726 } 727 728 test_bind_and_connect(_metadata, &self->srv0, false, false); 729 730 test_bind_and_connect(_metadata, &self->srv1, false, 731 is_restricted(&variant->prot, variant->sandbox)); 732 733 test_bind_and_connect(_metadata, &self->srv2, 734 is_restricted(&variant->prot, variant->sandbox), 735 is_restricted(&variant->prot, variant->sandbox)); 736 } 737 738 TEST_F(protocol, bind_unspec) 739 { 740 const struct landlock_ruleset_attr ruleset_attr = { 741 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 742 }; 743 const struct landlock_net_port_attr tcp_bind = { 744 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 745 .port = self->srv0.port, 746 }; 747 int bind_fd, ret; 748 749 if (variant->sandbox == TCP_SANDBOX) { 750 const int ruleset_fd = landlock_create_ruleset( 751 &ruleset_attr, sizeof(ruleset_attr), 0); 752 ASSERT_LE(0, ruleset_fd); 753 754 /* Allows bind. */ 755 ASSERT_EQ(0, 756 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 757 &tcp_bind, 0)); 758 enforce_ruleset(_metadata, ruleset_fd); 759 EXPECT_EQ(0, close(ruleset_fd)); 760 } 761 762 bind_fd = socket_variant(&self->srv0); 763 ASSERT_LE(0, bind_fd); 764 765 /* Tries to bind with too small addrlen. */ 766 EXPECT_EQ(-EINVAL, bind_variant_addrlen( 767 bind_fd, &self->unspec_any0, 768 get_addrlen(&self->unspec_any0, true) - 1)); 769 770 /* Allowed bind on AF_UNSPEC/INADDR_ANY. */ 771 ret = bind_variant(bind_fd, &self->unspec_any0); 772 if (variant->prot.domain == AF_INET) { 773 EXPECT_EQ(0, ret) 774 { 775 TH_LOG("Failed to bind to unspec/any socket: %s", 776 strerror(errno)); 777 } 778 } else if (variant->prot.domain == AF_INET6) { 779 EXPECT_EQ(-EAFNOSUPPORT, ret); 780 } else { 781 EXPECT_EQ(-EINVAL, ret); 782 } 783 EXPECT_EQ(0, close(bind_fd)); 784 785 if (variant->sandbox == TCP_SANDBOX) { 786 const int ruleset_fd = landlock_create_ruleset( 787 &ruleset_attr, sizeof(ruleset_attr), 0); 788 ASSERT_LE(0, ruleset_fd); 789 790 /* Denies bind. */ 791 enforce_ruleset(_metadata, ruleset_fd); 792 EXPECT_EQ(0, close(ruleset_fd)); 793 } 794 795 bind_fd = socket_variant(&self->srv0); 796 ASSERT_LE(0, bind_fd); 797 798 /* Denied bind on AF_UNSPEC/INADDR_ANY. */ 799 ret = bind_variant(bind_fd, &self->unspec_any0); 800 if (variant->prot.domain == AF_INET) { 801 if (is_restricted(&variant->prot, variant->sandbox)) { 802 EXPECT_EQ(-EACCES, ret); 803 } else { 804 EXPECT_EQ(0, ret); 805 } 806 } else if (variant->prot.domain == AF_INET6) { 807 EXPECT_EQ(-EAFNOSUPPORT, ret); 808 } else { 809 EXPECT_EQ(-EINVAL, ret); 810 } 811 EXPECT_EQ(0, close(bind_fd)); 812 813 /* Checks bind with AF_UNSPEC and the loopback address. */ 814 bind_fd = socket_variant(&self->srv0); 815 ASSERT_LE(0, bind_fd); 816 ret = bind_variant(bind_fd, &self->unspec_srv0); 817 if (variant->prot.domain == AF_INET || 818 variant->prot.domain == AF_INET6) { 819 EXPECT_EQ(-EAFNOSUPPORT, ret); 820 } else { 821 EXPECT_EQ(-EINVAL, ret) 822 { 823 TH_LOG("Wrong bind error: %s", strerror(errno)); 824 } 825 } 826 EXPECT_EQ(0, close(bind_fd)); 827 } 828 829 TEST_F(protocol, connect_unspec) 830 { 831 const struct landlock_ruleset_attr ruleset_attr = { 832 .handled_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP, 833 }; 834 const struct landlock_net_port_attr tcp_connect = { 835 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP, 836 .port = self->srv0.port, 837 }; 838 int bind_fd, client_fd, status; 839 pid_t child; 840 841 /* Specific connection tests. */ 842 bind_fd = socket_variant(&self->srv0); 843 ASSERT_LE(0, bind_fd); 844 EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0)); 845 if (self->srv0.protocol.type == SOCK_STREAM) 846 EXPECT_EQ(0, listen(bind_fd, backlog)); 847 848 child = fork(); 849 ASSERT_LE(0, child); 850 if (child == 0) { 851 int connect_fd, ret; 852 853 /* Closes listening socket for the child. */ 854 EXPECT_EQ(0, close(bind_fd)); 855 856 connect_fd = socket_variant(&self->srv0); 857 ASSERT_LE(0, connect_fd); 858 EXPECT_EQ(0, connect_variant(connect_fd, &self->srv0)); 859 860 /* Tries to connect again, or set peer. */ 861 ret = connect_variant(connect_fd, &self->srv0); 862 if (self->srv0.protocol.type == SOCK_STREAM) { 863 EXPECT_EQ(-EISCONN, ret); 864 } else { 865 EXPECT_EQ(0, ret); 866 } 867 868 if (variant->sandbox == TCP_SANDBOX) { 869 const int ruleset_fd = landlock_create_ruleset( 870 &ruleset_attr, sizeof(ruleset_attr), 0); 871 ASSERT_LE(0, ruleset_fd); 872 873 /* Allows connect. */ 874 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, 875 LANDLOCK_RULE_NET_PORT, 876 &tcp_connect, 0)); 877 enforce_ruleset(_metadata, ruleset_fd); 878 EXPECT_EQ(0, close(ruleset_fd)); 879 } 880 881 /* Disconnects already connected socket, or set peer. */ 882 ret = connect_variant(connect_fd, &self->unspec_any0); 883 if (self->srv0.protocol.domain == AF_UNIX && 884 self->srv0.protocol.type == SOCK_STREAM) { 885 EXPECT_EQ(-EINVAL, ret); 886 } else { 887 EXPECT_EQ(0, ret); 888 } 889 890 /* Tries to reconnect, or set peer. */ 891 ret = connect_variant(connect_fd, &self->srv0); 892 if (self->srv0.protocol.domain == AF_UNIX && 893 self->srv0.protocol.type == SOCK_STREAM) { 894 EXPECT_EQ(-EISCONN, ret); 895 } else { 896 EXPECT_EQ(0, ret); 897 } 898 899 if (variant->sandbox == TCP_SANDBOX) { 900 const int ruleset_fd = landlock_create_ruleset( 901 &ruleset_attr, sizeof(ruleset_attr), 0); 902 ASSERT_LE(0, ruleset_fd); 903 904 /* Denies connect. */ 905 enforce_ruleset(_metadata, ruleset_fd); 906 EXPECT_EQ(0, close(ruleset_fd)); 907 } 908 909 /* Try to re-disconnect with a truncated address struct. */ 910 EXPECT_EQ(-EINVAL, 911 connect_variant_addrlen( 912 connect_fd, &self->unspec_any0, 913 get_addrlen(&self->unspec_any0, true) - 1)); 914 915 /* 916 * Re-disconnect, with a minimal sockaddr struct (just a 917 * bare af_family=AF_UNSPEC field). 918 */ 919 ret = connect_variant_addrlen(connect_fd, &self->unspec_any0, 920 get_addrlen(&self->unspec_any0, 921 true)); 922 if (self->srv0.protocol.domain == AF_UNIX && 923 self->srv0.protocol.type == SOCK_STREAM) { 924 EXPECT_EQ(-EINVAL, ret); 925 } else { 926 /* Always allowed to disconnect. */ 927 EXPECT_EQ(0, ret); 928 } 929 930 EXPECT_EQ(0, close(connect_fd)); 931 _exit(_metadata->exit_code); 932 return; 933 } 934 935 client_fd = bind_fd; 936 if (self->srv0.protocol.type == SOCK_STREAM) { 937 client_fd = accept(bind_fd, NULL, 0); 938 ASSERT_LE(0, client_fd); 939 } 940 941 EXPECT_EQ(child, waitpid(child, &status, 0)); 942 EXPECT_EQ(1, WIFEXITED(status)); 943 EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 944 945 /* Closes connection, if any. */ 946 if (client_fd != bind_fd) 947 EXPECT_LE(0, close(client_fd)); 948 949 /* Closes listening socket. */ 950 EXPECT_EQ(0, close(bind_fd)); 951 } 952 953 FIXTURE(ipv4) 954 { 955 struct service_fixture srv0, srv1; 956 }; 957 958 FIXTURE_VARIANT(ipv4) 959 { 960 const enum sandbox_type sandbox; 961 const int type; 962 }; 963 964 /* clang-format off */ 965 FIXTURE_VARIANT_ADD(ipv4, no_sandbox_with_tcp) { 966 /* clang-format on */ 967 .sandbox = NO_SANDBOX, 968 .type = SOCK_STREAM, 969 }; 970 971 /* clang-format off */ 972 FIXTURE_VARIANT_ADD(ipv4, tcp_sandbox_with_tcp) { 973 /* clang-format on */ 974 .sandbox = TCP_SANDBOX, 975 .type = SOCK_STREAM, 976 }; 977 978 /* clang-format off */ 979 FIXTURE_VARIANT_ADD(ipv4, no_sandbox_with_udp) { 980 /* clang-format on */ 981 .sandbox = NO_SANDBOX, 982 .type = SOCK_DGRAM, 983 }; 984 985 /* clang-format off */ 986 FIXTURE_VARIANT_ADD(ipv4, tcp_sandbox_with_udp) { 987 /* clang-format on */ 988 .sandbox = TCP_SANDBOX, 989 .type = SOCK_DGRAM, 990 }; 991 992 FIXTURE_SETUP(ipv4) 993 { 994 const struct protocol_variant prot = { 995 .domain = AF_INET, 996 .type = variant->type, 997 }; 998 999 disable_caps(_metadata); 1000 1001 set_service(&self->srv0, prot, 0); 1002 set_service(&self->srv1, prot, 1); 1003 1004 setup_loopback(_metadata); 1005 }; 1006 1007 FIXTURE_TEARDOWN(ipv4) 1008 { 1009 } 1010 1011 TEST_F(ipv4, from_unix_to_inet) 1012 { 1013 int unix_stream_fd, unix_dgram_fd; 1014 1015 if (variant->sandbox == TCP_SANDBOX) { 1016 const struct landlock_ruleset_attr ruleset_attr = { 1017 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1018 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1019 }; 1020 const struct landlock_net_port_attr tcp_bind_connect_p0 = { 1021 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1022 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1023 .port = self->srv0.port, 1024 }; 1025 int ruleset_fd; 1026 1027 /* Denies connect and bind to check errno value. */ 1028 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1029 sizeof(ruleset_attr), 0); 1030 ASSERT_LE(0, ruleset_fd); 1031 1032 /* Allows connect and bind for srv0. */ 1033 ASSERT_EQ(0, 1034 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1035 &tcp_bind_connect_p0, 0)); 1036 1037 enforce_ruleset(_metadata, ruleset_fd); 1038 EXPECT_EQ(0, close(ruleset_fd)); 1039 } 1040 1041 unix_stream_fd = socket(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0); 1042 ASSERT_LE(0, unix_stream_fd); 1043 1044 unix_dgram_fd = socket(AF_UNIX, SOCK_DGRAM | SOCK_CLOEXEC, 0); 1045 ASSERT_LE(0, unix_dgram_fd); 1046 1047 /* Checks unix stream bind and connect for srv0. */ 1048 EXPECT_EQ(-EINVAL, bind_variant(unix_stream_fd, &self->srv0)); 1049 EXPECT_EQ(-EINVAL, connect_variant(unix_stream_fd, &self->srv0)); 1050 1051 /* Checks unix stream bind and connect for srv1. */ 1052 EXPECT_EQ(-EINVAL, bind_variant(unix_stream_fd, &self->srv1)) 1053 { 1054 TH_LOG("Wrong bind error: %s", strerror(errno)); 1055 } 1056 EXPECT_EQ(-EINVAL, connect_variant(unix_stream_fd, &self->srv1)); 1057 1058 /* Checks unix datagram bind and connect for srv0. */ 1059 EXPECT_EQ(-EINVAL, bind_variant(unix_dgram_fd, &self->srv0)); 1060 EXPECT_EQ(-EINVAL, connect_variant(unix_dgram_fd, &self->srv0)); 1061 1062 /* Checks unix datagram bind and connect for srv1. */ 1063 EXPECT_EQ(-EINVAL, bind_variant(unix_dgram_fd, &self->srv1)); 1064 EXPECT_EQ(-EINVAL, connect_variant(unix_dgram_fd, &self->srv1)); 1065 } 1066 1067 FIXTURE(tcp_layers) 1068 { 1069 struct service_fixture srv0, srv1; 1070 }; 1071 1072 FIXTURE_VARIANT(tcp_layers) 1073 { 1074 const size_t num_layers; 1075 const int domain; 1076 }; 1077 1078 FIXTURE_SETUP(tcp_layers) 1079 { 1080 const struct protocol_variant prot = { 1081 .domain = variant->domain, 1082 .type = SOCK_STREAM, 1083 }; 1084 1085 disable_caps(_metadata); 1086 1087 ASSERT_EQ(0, set_service(&self->srv0, prot, 0)); 1088 ASSERT_EQ(0, set_service(&self->srv1, prot, 1)); 1089 1090 setup_loopback(_metadata); 1091 }; 1092 1093 FIXTURE_TEARDOWN(tcp_layers) 1094 { 1095 } 1096 1097 /* clang-format off */ 1098 FIXTURE_VARIANT_ADD(tcp_layers, no_sandbox_with_ipv4) { 1099 /* clang-format on */ 1100 .domain = AF_INET, 1101 .num_layers = 0, 1102 }; 1103 1104 /* clang-format off */ 1105 FIXTURE_VARIANT_ADD(tcp_layers, one_sandbox_with_ipv4) { 1106 /* clang-format on */ 1107 .domain = AF_INET, 1108 .num_layers = 1, 1109 }; 1110 1111 /* clang-format off */ 1112 FIXTURE_VARIANT_ADD(tcp_layers, two_sandboxes_with_ipv4) { 1113 /* clang-format on */ 1114 .domain = AF_INET, 1115 .num_layers = 2, 1116 }; 1117 1118 /* clang-format off */ 1119 FIXTURE_VARIANT_ADD(tcp_layers, three_sandboxes_with_ipv4) { 1120 /* clang-format on */ 1121 .domain = AF_INET, 1122 .num_layers = 3, 1123 }; 1124 1125 /* clang-format off */ 1126 FIXTURE_VARIANT_ADD(tcp_layers, no_sandbox_with_ipv6) { 1127 /* clang-format on */ 1128 .domain = AF_INET6, 1129 .num_layers = 0, 1130 }; 1131 1132 /* clang-format off */ 1133 FIXTURE_VARIANT_ADD(tcp_layers, one_sandbox_with_ipv6) { 1134 /* clang-format on */ 1135 .domain = AF_INET6, 1136 .num_layers = 1, 1137 }; 1138 1139 /* clang-format off */ 1140 FIXTURE_VARIANT_ADD(tcp_layers, two_sandboxes_with_ipv6) { 1141 /* clang-format on */ 1142 .domain = AF_INET6, 1143 .num_layers = 2, 1144 }; 1145 1146 /* clang-format off */ 1147 FIXTURE_VARIANT_ADD(tcp_layers, three_sandboxes_with_ipv6) { 1148 /* clang-format on */ 1149 .domain = AF_INET6, 1150 .num_layers = 3, 1151 }; 1152 1153 TEST_F(tcp_layers, ruleset_overlap) 1154 { 1155 const struct landlock_ruleset_attr ruleset_attr = { 1156 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1157 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1158 }; 1159 const struct landlock_net_port_attr tcp_bind = { 1160 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1161 .port = self->srv0.port, 1162 }; 1163 const struct landlock_net_port_attr tcp_bind_connect = { 1164 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1165 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1166 .port = self->srv0.port, 1167 }; 1168 1169 if (variant->num_layers >= 1) { 1170 int ruleset_fd; 1171 1172 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1173 sizeof(ruleset_attr), 0); 1174 ASSERT_LE(0, ruleset_fd); 1175 1176 /* Allows bind. */ 1177 ASSERT_EQ(0, 1178 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1179 &tcp_bind, 0)); 1180 /* Also allows bind, but allows connect too. */ 1181 ASSERT_EQ(0, 1182 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1183 &tcp_bind_connect, 0)); 1184 enforce_ruleset(_metadata, ruleset_fd); 1185 EXPECT_EQ(0, close(ruleset_fd)); 1186 } 1187 1188 if (variant->num_layers >= 2) { 1189 int ruleset_fd; 1190 1191 /* Creates another ruleset layer. */ 1192 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1193 sizeof(ruleset_attr), 0); 1194 ASSERT_LE(0, ruleset_fd); 1195 1196 /* Only allows bind. */ 1197 ASSERT_EQ(0, 1198 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1199 &tcp_bind, 0)); 1200 enforce_ruleset(_metadata, ruleset_fd); 1201 EXPECT_EQ(0, close(ruleset_fd)); 1202 } 1203 1204 if (variant->num_layers >= 3) { 1205 int ruleset_fd; 1206 1207 /* Creates another ruleset layer. */ 1208 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1209 sizeof(ruleset_attr), 0); 1210 ASSERT_LE(0, ruleset_fd); 1211 1212 /* Try to allow bind and connect. */ 1213 ASSERT_EQ(0, 1214 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1215 &tcp_bind_connect, 0)); 1216 enforce_ruleset(_metadata, ruleset_fd); 1217 EXPECT_EQ(0, close(ruleset_fd)); 1218 } 1219 1220 /* 1221 * Forbids to connect to the socket because only one ruleset layer 1222 * allows connect. 1223 */ 1224 test_bind_and_connect(_metadata, &self->srv0, false, 1225 variant->num_layers >= 2); 1226 } 1227 1228 TEST_F(tcp_layers, ruleset_expand) 1229 { 1230 if (variant->num_layers >= 1) { 1231 const struct landlock_ruleset_attr ruleset_attr = { 1232 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 1233 }; 1234 /* Allows bind for srv0. */ 1235 const struct landlock_net_port_attr bind_srv0 = { 1236 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1237 .port = self->srv0.port, 1238 }; 1239 int ruleset_fd; 1240 1241 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1242 sizeof(ruleset_attr), 0); 1243 ASSERT_LE(0, ruleset_fd); 1244 ASSERT_EQ(0, 1245 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1246 &bind_srv0, 0)); 1247 enforce_ruleset(_metadata, ruleset_fd); 1248 EXPECT_EQ(0, close(ruleset_fd)); 1249 } 1250 1251 if (variant->num_layers >= 2) { 1252 /* Expands network mask with connect action. */ 1253 const struct landlock_ruleset_attr ruleset_attr = { 1254 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1255 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1256 }; 1257 /* Allows bind for srv0 and connect to srv0. */ 1258 const struct landlock_net_port_attr tcp_bind_connect_p0 = { 1259 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1260 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1261 .port = self->srv0.port, 1262 }; 1263 /* Try to allow bind for srv1. */ 1264 const struct landlock_net_port_attr tcp_bind_p1 = { 1265 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1266 .port = self->srv1.port, 1267 }; 1268 int ruleset_fd; 1269 1270 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1271 sizeof(ruleset_attr), 0); 1272 ASSERT_LE(0, ruleset_fd); 1273 ASSERT_EQ(0, 1274 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1275 &tcp_bind_connect_p0, 0)); 1276 ASSERT_EQ(0, 1277 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1278 &tcp_bind_p1, 0)); 1279 enforce_ruleset(_metadata, ruleset_fd); 1280 EXPECT_EQ(0, close(ruleset_fd)); 1281 } 1282 1283 if (variant->num_layers >= 3) { 1284 const struct landlock_ruleset_attr ruleset_attr = { 1285 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1286 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1287 }; 1288 /* Allows connect to srv0, without bind rule. */ 1289 const struct landlock_net_port_attr tcp_bind_p0 = { 1290 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1291 .port = self->srv0.port, 1292 }; 1293 int ruleset_fd; 1294 1295 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1296 sizeof(ruleset_attr), 0); 1297 ASSERT_LE(0, ruleset_fd); 1298 ASSERT_EQ(0, 1299 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1300 &tcp_bind_p0, 0)); 1301 enforce_ruleset(_metadata, ruleset_fd); 1302 EXPECT_EQ(0, close(ruleset_fd)); 1303 } 1304 1305 test_bind_and_connect(_metadata, &self->srv0, false, 1306 variant->num_layers >= 3); 1307 1308 test_bind_and_connect(_metadata, &self->srv1, variant->num_layers >= 1, 1309 variant->num_layers >= 2); 1310 } 1311 1312 /* clang-format off */ 1313 FIXTURE(mini) {}; 1314 /* clang-format on */ 1315 1316 FIXTURE_SETUP(mini) 1317 { 1318 disable_caps(_metadata); 1319 1320 setup_loopback(_metadata); 1321 }; 1322 1323 FIXTURE_TEARDOWN(mini) 1324 { 1325 } 1326 1327 /* clang-format off */ 1328 1329 #define ACCESS_LAST LANDLOCK_ACCESS_NET_CONNECT_TCP 1330 1331 #define ACCESS_ALL ( \ 1332 LANDLOCK_ACCESS_NET_BIND_TCP | \ 1333 LANDLOCK_ACCESS_NET_CONNECT_TCP) 1334 1335 /* clang-format on */ 1336 1337 TEST_F(mini, network_access_rights) 1338 { 1339 const struct landlock_ruleset_attr ruleset_attr = { 1340 .handled_access_net = ACCESS_ALL, 1341 }; 1342 struct landlock_net_port_attr net_port = { 1343 .port = sock_port_start, 1344 }; 1345 int ruleset_fd; 1346 __u64 access; 1347 1348 ruleset_fd = 1349 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1350 ASSERT_LE(0, ruleset_fd); 1351 1352 for (access = 1; access <= ACCESS_LAST; access <<= 1) { 1353 net_port.allowed_access = access; 1354 EXPECT_EQ(0, 1355 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1356 &net_port, 0)) 1357 { 1358 TH_LOG("Failed to add rule with access 0x%llx: %s", 1359 access, strerror(errno)); 1360 } 1361 } 1362 EXPECT_EQ(0, close(ruleset_fd)); 1363 } 1364 1365 /* Checks invalid attribute, out of landlock network access range. */ 1366 TEST_F(mini, ruleset_with_unknown_access) 1367 { 1368 __u64 access_mask; 1369 1370 for (access_mask = 1ULL << 63; access_mask != ACCESS_LAST; 1371 access_mask >>= 1) { 1372 const struct landlock_ruleset_attr ruleset_attr = { 1373 .handled_access_net = access_mask, 1374 }; 1375 1376 EXPECT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 1377 sizeof(ruleset_attr), 0)); 1378 EXPECT_EQ(EINVAL, errno); 1379 } 1380 } 1381 1382 TEST_F(mini, rule_with_unknown_access) 1383 { 1384 const struct landlock_ruleset_attr ruleset_attr = { 1385 .handled_access_net = ACCESS_ALL, 1386 }; 1387 struct landlock_net_port_attr net_port = { 1388 .port = sock_port_start, 1389 }; 1390 int ruleset_fd; 1391 __u64 access; 1392 1393 ruleset_fd = 1394 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1395 ASSERT_LE(0, ruleset_fd); 1396 1397 for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) { 1398 net_port.allowed_access = access; 1399 EXPECT_EQ(-1, 1400 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1401 &net_port, 0)); 1402 EXPECT_EQ(EINVAL, errno); 1403 } 1404 EXPECT_EQ(0, close(ruleset_fd)); 1405 } 1406 1407 TEST_F(mini, rule_with_unhandled_access) 1408 { 1409 struct landlock_ruleset_attr ruleset_attr = { 1410 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 1411 }; 1412 struct landlock_net_port_attr net_port = { 1413 .port = sock_port_start, 1414 }; 1415 int ruleset_fd; 1416 __u64 access; 1417 1418 ruleset_fd = 1419 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1420 ASSERT_LE(0, ruleset_fd); 1421 1422 for (access = 1; access > 0; access <<= 1) { 1423 int err; 1424 1425 net_port.allowed_access = access; 1426 err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1427 &net_port, 0); 1428 if (access == ruleset_attr.handled_access_net) { 1429 EXPECT_EQ(0, err); 1430 } else { 1431 EXPECT_EQ(-1, err); 1432 EXPECT_EQ(EINVAL, errno); 1433 } 1434 } 1435 1436 EXPECT_EQ(0, close(ruleset_fd)); 1437 } 1438 1439 TEST_F(mini, inval) 1440 { 1441 const struct landlock_ruleset_attr ruleset_attr = { 1442 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP 1443 }; 1444 const struct landlock_net_port_attr tcp_bind_connect = { 1445 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1446 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1447 .port = sock_port_start, 1448 }; 1449 const struct landlock_net_port_attr tcp_denied = { 1450 .allowed_access = 0, 1451 .port = sock_port_start, 1452 }; 1453 const struct landlock_net_port_attr tcp_bind = { 1454 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1455 .port = sock_port_start, 1456 }; 1457 int ruleset_fd; 1458 1459 ruleset_fd = 1460 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1461 ASSERT_LE(0, ruleset_fd); 1462 1463 /* Checks unhandled allowed_access. */ 1464 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1465 &tcp_bind_connect, 0)); 1466 EXPECT_EQ(EINVAL, errno); 1467 1468 /* Checks zero access value. */ 1469 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1470 &tcp_denied, 0)); 1471 EXPECT_EQ(ENOMSG, errno); 1472 1473 /* Adds with legitimate values. */ 1474 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1475 &tcp_bind, 0)); 1476 } 1477 1478 TEST_F(mini, tcp_port_overflow) 1479 { 1480 const struct landlock_ruleset_attr ruleset_attr = { 1481 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1482 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1483 }; 1484 const struct landlock_net_port_attr port_max_bind = { 1485 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1486 .port = UINT16_MAX, 1487 }; 1488 const struct landlock_net_port_attr port_max_connect = { 1489 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP, 1490 .port = UINT16_MAX, 1491 }; 1492 const struct landlock_net_port_attr port_overflow1 = { 1493 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1494 .port = UINT16_MAX + 1, 1495 }; 1496 const struct landlock_net_port_attr port_overflow2 = { 1497 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1498 .port = UINT16_MAX + 2, 1499 }; 1500 const struct landlock_net_port_attr port_overflow3 = { 1501 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1502 .port = UINT32_MAX + 1UL, 1503 }; 1504 const struct landlock_net_port_attr port_overflow4 = { 1505 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1506 .port = UINT32_MAX + 2UL, 1507 }; 1508 const struct protocol_variant ipv4_tcp = { 1509 .domain = AF_INET, 1510 .type = SOCK_STREAM, 1511 }; 1512 struct service_fixture srv_denied, srv_max_allowed; 1513 int ruleset_fd; 1514 1515 ASSERT_EQ(0, set_service(&srv_denied, ipv4_tcp, 0)); 1516 1517 /* Be careful to avoid port inconsistencies. */ 1518 srv_max_allowed = srv_denied; 1519 srv_max_allowed.port = port_max_bind.port; 1520 srv_max_allowed.ipv4_addr.sin_port = htons(port_max_bind.port); 1521 1522 ruleset_fd = 1523 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1524 ASSERT_LE(0, ruleset_fd); 1525 1526 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1527 &port_max_bind, 0)); 1528 1529 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1530 &port_overflow1, 0)); 1531 EXPECT_EQ(EINVAL, errno); 1532 1533 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1534 &port_overflow2, 0)); 1535 EXPECT_EQ(EINVAL, errno); 1536 1537 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1538 &port_overflow3, 0)); 1539 EXPECT_EQ(EINVAL, errno); 1540 1541 /* Interleaves with invalid rule additions. */ 1542 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1543 &port_max_connect, 0)); 1544 1545 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1546 &port_overflow4, 0)); 1547 EXPECT_EQ(EINVAL, errno); 1548 1549 enforce_ruleset(_metadata, ruleset_fd); 1550 1551 test_bind_and_connect(_metadata, &srv_denied, true, true); 1552 test_bind_and_connect(_metadata, &srv_max_allowed, false, false); 1553 } 1554 1555 FIXTURE(ipv4_tcp) 1556 { 1557 struct service_fixture srv0, srv1; 1558 }; 1559 1560 FIXTURE_SETUP(ipv4_tcp) 1561 { 1562 const struct protocol_variant ipv4_tcp = { 1563 .domain = AF_INET, 1564 .type = SOCK_STREAM, 1565 }; 1566 1567 disable_caps(_metadata); 1568 1569 ASSERT_EQ(0, set_service(&self->srv0, ipv4_tcp, 0)); 1570 ASSERT_EQ(0, set_service(&self->srv1, ipv4_tcp, 1)); 1571 1572 setup_loopback(_metadata); 1573 }; 1574 1575 FIXTURE_TEARDOWN(ipv4_tcp) 1576 { 1577 } 1578 1579 TEST_F(ipv4_tcp, port_endianness) 1580 { 1581 const struct landlock_ruleset_attr ruleset_attr = { 1582 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1583 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1584 }; 1585 const struct landlock_net_port_attr bind_host_endian_p0 = { 1586 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1587 /* Host port format. */ 1588 .port = self->srv0.port, 1589 }; 1590 const struct landlock_net_port_attr connect_big_endian_p0 = { 1591 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP, 1592 /* Big endian port format. */ 1593 .port = htons(self->srv0.port), 1594 }; 1595 const struct landlock_net_port_attr bind_connect_host_endian_p1 = { 1596 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1597 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1598 /* Host port format. */ 1599 .port = self->srv1.port, 1600 }; 1601 const unsigned int one = 1; 1602 const char little_endian = *(const char *)&one; 1603 int ruleset_fd; 1604 1605 ruleset_fd = 1606 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1607 ASSERT_LE(0, ruleset_fd); 1608 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1609 &bind_host_endian_p0, 0)); 1610 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1611 &connect_big_endian_p0, 0)); 1612 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1613 &bind_connect_host_endian_p1, 0)); 1614 enforce_ruleset(_metadata, ruleset_fd); 1615 1616 /* No restriction for big endinan CPU. */ 1617 test_bind_and_connect(_metadata, &self->srv0, false, little_endian); 1618 1619 /* No restriction for any CPU. */ 1620 test_bind_and_connect(_metadata, &self->srv1, false, false); 1621 } 1622 1623 TEST_F(ipv4_tcp, with_fs) 1624 { 1625 const struct landlock_ruleset_attr ruleset_attr_fs_net = { 1626 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 1627 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 1628 }; 1629 struct landlock_path_beneath_attr path_beneath = { 1630 .allowed_access = LANDLOCK_ACCESS_FS_READ_DIR, 1631 .parent_fd = -1, 1632 }; 1633 struct landlock_net_port_attr tcp_bind = { 1634 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1635 .port = self->srv0.port, 1636 }; 1637 int ruleset_fd, bind_fd, dir_fd; 1638 1639 /* Creates ruleset both for filesystem and network access. */ 1640 ruleset_fd = landlock_create_ruleset(&ruleset_attr_fs_net, 1641 sizeof(ruleset_attr_fs_net), 0); 1642 ASSERT_LE(0, ruleset_fd); 1643 1644 /* Adds a filesystem rule. */ 1645 path_beneath.parent_fd = open("/dev", O_PATH | O_DIRECTORY | O_CLOEXEC); 1646 ASSERT_LE(0, path_beneath.parent_fd); 1647 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 1648 &path_beneath, 0)); 1649 EXPECT_EQ(0, close(path_beneath.parent_fd)); 1650 1651 /* Adds a network rule. */ 1652 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1653 &tcp_bind, 0)); 1654 1655 enforce_ruleset(_metadata, ruleset_fd); 1656 EXPECT_EQ(0, close(ruleset_fd)); 1657 1658 /* Tests file access. */ 1659 dir_fd = open("/dev", O_RDONLY); 1660 EXPECT_LE(0, dir_fd); 1661 EXPECT_EQ(0, close(dir_fd)); 1662 1663 dir_fd = open("/", O_RDONLY); 1664 EXPECT_EQ(-1, dir_fd); 1665 EXPECT_EQ(EACCES, errno); 1666 1667 /* Tests port binding. */ 1668 bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 1669 ASSERT_LE(0, bind_fd); 1670 EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0)); 1671 EXPECT_EQ(0, close(bind_fd)); 1672 1673 bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 1674 ASSERT_LE(0, bind_fd); 1675 EXPECT_EQ(-EACCES, bind_variant(bind_fd, &self->srv1)); 1676 } 1677 1678 FIXTURE(port_specific) 1679 { 1680 struct service_fixture srv0; 1681 }; 1682 1683 FIXTURE_VARIANT(port_specific) 1684 { 1685 const enum sandbox_type sandbox; 1686 const struct protocol_variant prot; 1687 }; 1688 1689 /* clang-format off */ 1690 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv4) { 1691 /* clang-format on */ 1692 .sandbox = NO_SANDBOX, 1693 .prot = { 1694 .domain = AF_INET, 1695 .type = SOCK_STREAM, 1696 }, 1697 }; 1698 1699 /* clang-format off */ 1700 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv4) { 1701 /* clang-format on */ 1702 .sandbox = TCP_SANDBOX, 1703 .prot = { 1704 .domain = AF_INET, 1705 .type = SOCK_STREAM, 1706 }, 1707 }; 1708 1709 /* clang-format off */ 1710 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv6) { 1711 /* clang-format on */ 1712 .sandbox = NO_SANDBOX, 1713 .prot = { 1714 .domain = AF_INET6, 1715 .type = SOCK_STREAM, 1716 }, 1717 }; 1718 1719 /* clang-format off */ 1720 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv6) { 1721 /* clang-format on */ 1722 .sandbox = TCP_SANDBOX, 1723 .prot = { 1724 .domain = AF_INET6, 1725 .type = SOCK_STREAM, 1726 }, 1727 }; 1728 1729 FIXTURE_SETUP(port_specific) 1730 { 1731 disable_caps(_metadata); 1732 1733 ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0)); 1734 1735 setup_loopback(_metadata); 1736 }; 1737 1738 FIXTURE_TEARDOWN(port_specific) 1739 { 1740 } 1741 1742 TEST_F(port_specific, bind_connect_zero) 1743 { 1744 int bind_fd, connect_fd, ret; 1745 uint16_t port; 1746 1747 /* Adds a rule layer with bind and connect actions. */ 1748 if (variant->sandbox == TCP_SANDBOX) { 1749 const struct landlock_ruleset_attr ruleset_attr = { 1750 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1751 LANDLOCK_ACCESS_NET_CONNECT_TCP 1752 }; 1753 const struct landlock_net_port_attr tcp_bind_connect_zero = { 1754 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1755 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1756 .port = 0, 1757 }; 1758 int ruleset_fd; 1759 1760 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1761 sizeof(ruleset_attr), 0); 1762 ASSERT_LE(0, ruleset_fd); 1763 1764 /* Checks zero port value on bind and connect actions. */ 1765 EXPECT_EQ(0, 1766 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1767 &tcp_bind_connect_zero, 0)); 1768 1769 enforce_ruleset(_metadata, ruleset_fd); 1770 EXPECT_EQ(0, close(ruleset_fd)); 1771 } 1772 1773 bind_fd = socket_variant(&self->srv0); 1774 ASSERT_LE(0, bind_fd); 1775 1776 connect_fd = socket_variant(&self->srv0); 1777 ASSERT_LE(0, connect_fd); 1778 1779 /* Sets address port to 0 for both protocol families. */ 1780 set_port(&self->srv0, 0); 1781 /* 1782 * Binds on port 0, which selects a random port within 1783 * ip_local_port_range. 1784 */ 1785 ret = bind_variant(bind_fd, &self->srv0); 1786 EXPECT_EQ(0, ret); 1787 1788 EXPECT_EQ(0, listen(bind_fd, backlog)); 1789 1790 /* Connects on port 0. */ 1791 ret = connect_variant(connect_fd, &self->srv0); 1792 EXPECT_EQ(-ECONNREFUSED, ret); 1793 1794 /* Sets binded port for both protocol families. */ 1795 port = get_binded_port(bind_fd, &variant->prot); 1796 EXPECT_NE(0, port); 1797 set_port(&self->srv0, port); 1798 /* Connects on the binded port. */ 1799 ret = connect_variant(connect_fd, &self->srv0); 1800 if (is_restricted(&variant->prot, variant->sandbox)) { 1801 /* Denied by Landlock. */ 1802 EXPECT_EQ(-EACCES, ret); 1803 } else { 1804 EXPECT_EQ(0, ret); 1805 } 1806 1807 EXPECT_EQ(0, close(connect_fd)); 1808 EXPECT_EQ(0, close(bind_fd)); 1809 } 1810 1811 TEST_F(port_specific, bind_connect_1023) 1812 { 1813 int bind_fd, connect_fd, ret; 1814 1815 /* Adds a rule layer with bind and connect actions. */ 1816 if (variant->sandbox == TCP_SANDBOX) { 1817 const struct landlock_ruleset_attr ruleset_attr = { 1818 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1819 LANDLOCK_ACCESS_NET_CONNECT_TCP 1820 }; 1821 /* A rule with port value less than 1024. */ 1822 const struct landlock_net_port_attr tcp_bind_connect_low_range = { 1823 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1824 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1825 .port = 1023, 1826 }; 1827 /* A rule with 1024 port. */ 1828 const struct landlock_net_port_attr tcp_bind_connect = { 1829 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1830 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1831 .port = 1024, 1832 }; 1833 int ruleset_fd; 1834 1835 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1836 sizeof(ruleset_attr), 0); 1837 ASSERT_LE(0, ruleset_fd); 1838 1839 ASSERT_EQ(0, 1840 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1841 &tcp_bind_connect_low_range, 0)); 1842 ASSERT_EQ(0, 1843 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1844 &tcp_bind_connect, 0)); 1845 1846 enforce_ruleset(_metadata, ruleset_fd); 1847 EXPECT_EQ(0, close(ruleset_fd)); 1848 } 1849 1850 bind_fd = socket_variant(&self->srv0); 1851 ASSERT_LE(0, bind_fd); 1852 1853 connect_fd = socket_variant(&self->srv0); 1854 ASSERT_LE(0, connect_fd); 1855 1856 /* Sets address port to 1023 for both protocol families. */ 1857 set_port(&self->srv0, 1023); 1858 /* Binds on port 1023. */ 1859 ret = bind_variant(bind_fd, &self->srv0); 1860 /* Denied by the system. */ 1861 EXPECT_EQ(-EACCES, ret); 1862 1863 /* Binds on port 1023. */ 1864 set_cap(_metadata, CAP_NET_BIND_SERVICE); 1865 ret = bind_variant(bind_fd, &self->srv0); 1866 clear_cap(_metadata, CAP_NET_BIND_SERVICE); 1867 EXPECT_EQ(0, ret); 1868 EXPECT_EQ(0, listen(bind_fd, backlog)); 1869 1870 /* Connects on the binded port 1023. */ 1871 ret = connect_variant(connect_fd, &self->srv0); 1872 EXPECT_EQ(0, ret); 1873 1874 EXPECT_EQ(0, close(connect_fd)); 1875 EXPECT_EQ(0, close(bind_fd)); 1876 1877 bind_fd = socket_variant(&self->srv0); 1878 ASSERT_LE(0, bind_fd); 1879 1880 connect_fd = socket_variant(&self->srv0); 1881 ASSERT_LE(0, connect_fd); 1882 1883 /* Sets address port to 1024 for both protocol families. */ 1884 set_port(&self->srv0, 1024); 1885 /* Binds on port 1024. */ 1886 ret = bind_variant(bind_fd, &self->srv0); 1887 EXPECT_EQ(0, ret); 1888 EXPECT_EQ(0, listen(bind_fd, backlog)); 1889 1890 /* Connects on the binded port 1024. */ 1891 ret = connect_variant(connect_fd, &self->srv0); 1892 EXPECT_EQ(0, ret); 1893 1894 EXPECT_EQ(0, close(connect_fd)); 1895 EXPECT_EQ(0, close(bind_fd)); 1896 } 1897 1898 static int matches_log_tcp(const int audit_fd, const char *const blockers, 1899 const char *const dir_addr, const char *const addr, 1900 const char *const dir_port) 1901 { 1902 static const char log_template[] = REGEX_LANDLOCK_PREFIX 1903 " blockers=%s %s=%s %s=1024$"; 1904 /* 1905 * Max strlen(blockers): 16 1906 * Max strlen(dir_addr): 5 1907 * Max strlen(addr): 12 1908 * Max strlen(dir_port): 4 1909 */ 1910 char log_match[sizeof(log_template) + 37]; 1911 int log_match_len; 1912 1913 log_match_len = snprintf(log_match, sizeof(log_match), log_template, 1914 blockers, dir_addr, addr, dir_port); 1915 if (log_match_len > sizeof(log_match)) 1916 return -E2BIG; 1917 1918 return audit_match_record(audit_fd, AUDIT_LANDLOCK_ACCESS, log_match, 1919 NULL); 1920 } 1921 1922 FIXTURE(audit) 1923 { 1924 struct service_fixture srv0; 1925 struct audit_filter audit_filter; 1926 int audit_fd; 1927 }; 1928 1929 FIXTURE_VARIANT(audit) 1930 { 1931 const char *const addr; 1932 const struct protocol_variant prot; 1933 }; 1934 1935 /* clang-format off */ 1936 FIXTURE_VARIANT_ADD(audit, ipv4) { 1937 /* clang-format on */ 1938 .addr = "127\\.0\\.0\\.1", 1939 .prot = { 1940 .domain = AF_INET, 1941 .type = SOCK_STREAM, 1942 }, 1943 }; 1944 1945 /* clang-format off */ 1946 FIXTURE_VARIANT_ADD(audit, ipv6) { 1947 /* clang-format on */ 1948 .addr = "::1", 1949 .prot = { 1950 .domain = AF_INET6, 1951 .type = SOCK_STREAM, 1952 }, 1953 }; 1954 1955 FIXTURE_SETUP(audit) 1956 { 1957 ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0)); 1958 setup_loopback(_metadata); 1959 1960 set_cap(_metadata, CAP_AUDIT_CONTROL); 1961 self->audit_fd = audit_init_with_exe_filter(&self->audit_filter); 1962 EXPECT_LE(0, self->audit_fd); 1963 disable_caps(_metadata); 1964 }; 1965 1966 FIXTURE_TEARDOWN(audit) 1967 { 1968 set_cap(_metadata, CAP_AUDIT_CONTROL); 1969 EXPECT_EQ(0, audit_cleanup(self->audit_fd, &self->audit_filter)); 1970 clear_cap(_metadata, CAP_AUDIT_CONTROL); 1971 } 1972 1973 TEST_F(audit, bind) 1974 { 1975 const struct landlock_ruleset_attr ruleset_attr = { 1976 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1977 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1978 }; 1979 struct audit_records records; 1980 int ruleset_fd, sock_fd; 1981 1982 ruleset_fd = 1983 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1984 ASSERT_LE(0, ruleset_fd); 1985 enforce_ruleset(_metadata, ruleset_fd); 1986 EXPECT_EQ(0, close(ruleset_fd)); 1987 1988 sock_fd = socket_variant(&self->srv0); 1989 ASSERT_LE(0, sock_fd); 1990 EXPECT_EQ(-EACCES, bind_variant(sock_fd, &self->srv0)); 1991 EXPECT_EQ(0, matches_log_tcp(self->audit_fd, "net\\.bind_tcp", "saddr", 1992 variant->addr, "src")); 1993 1994 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 1995 EXPECT_EQ(0, records.access); 1996 EXPECT_EQ(1, records.domain); 1997 1998 EXPECT_EQ(0, close(sock_fd)); 1999 } 2000 2001 TEST_F(audit, connect) 2002 { 2003 const struct landlock_ruleset_attr ruleset_attr = { 2004 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 2005 LANDLOCK_ACCESS_NET_CONNECT_TCP, 2006 }; 2007 struct audit_records records; 2008 int ruleset_fd, sock_fd; 2009 2010 ruleset_fd = 2011 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 2012 ASSERT_LE(0, ruleset_fd); 2013 enforce_ruleset(_metadata, ruleset_fd); 2014 EXPECT_EQ(0, close(ruleset_fd)); 2015 2016 sock_fd = socket_variant(&self->srv0); 2017 ASSERT_LE(0, sock_fd); 2018 EXPECT_EQ(-EACCES, connect_variant(sock_fd, &self->srv0)); 2019 EXPECT_EQ(0, matches_log_tcp(self->audit_fd, "net\\.connect_tcp", 2020 "daddr", variant->addr, "dest")); 2021 2022 EXPECT_EQ(0, audit_count_records(self->audit_fd, &records)); 2023 EXPECT_EQ(0, records.access); 2024 EXPECT_EQ(1, records.domain); 2025 2026 EXPECT_EQ(0, close(sock_fd)); 2027 } 2028 2029 TEST_HARNESS_MAIN 2030