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