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