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