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, ruleset_with_unknown_access) 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, rule_with_unknown_access) 1280 { 1281 const struct landlock_ruleset_attr ruleset_attr = { 1282 .handled_access_net = ACCESS_ALL, 1283 }; 1284 struct landlock_net_port_attr net_port = { 1285 .port = sock_port_start, 1286 }; 1287 int ruleset_fd; 1288 __u64 access; 1289 1290 ruleset_fd = 1291 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1292 ASSERT_LE(0, ruleset_fd); 1293 1294 for (access = 1ULL << 63; access != ACCESS_LAST; access >>= 1) { 1295 net_port.allowed_access = access; 1296 EXPECT_EQ(-1, 1297 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1298 &net_port, 0)); 1299 EXPECT_EQ(EINVAL, errno); 1300 } 1301 EXPECT_EQ(0, close(ruleset_fd)); 1302 } 1303 1304 TEST_F(mini, rule_with_unhandled_access) 1305 { 1306 struct landlock_ruleset_attr ruleset_attr = { 1307 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 1308 }; 1309 struct landlock_net_port_attr net_port = { 1310 .port = sock_port_start, 1311 }; 1312 int ruleset_fd; 1313 __u64 access; 1314 1315 ruleset_fd = 1316 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1317 ASSERT_LE(0, ruleset_fd); 1318 1319 for (access = 1; access > 0; access <<= 1) { 1320 int err; 1321 1322 net_port.allowed_access = access; 1323 err = landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1324 &net_port, 0); 1325 if (access == ruleset_attr.handled_access_net) { 1326 EXPECT_EQ(0, err); 1327 } else { 1328 EXPECT_EQ(-1, err); 1329 EXPECT_EQ(EINVAL, errno); 1330 } 1331 } 1332 1333 EXPECT_EQ(0, close(ruleset_fd)); 1334 } 1335 1336 TEST_F(mini, inval) 1337 { 1338 const struct landlock_ruleset_attr ruleset_attr = { 1339 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP 1340 }; 1341 const struct landlock_net_port_attr tcp_bind_connect = { 1342 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1343 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1344 .port = sock_port_start, 1345 }; 1346 const struct landlock_net_port_attr tcp_denied = { 1347 .allowed_access = 0, 1348 .port = sock_port_start, 1349 }; 1350 const struct landlock_net_port_attr tcp_bind = { 1351 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1352 .port = sock_port_start, 1353 }; 1354 int ruleset_fd; 1355 1356 ruleset_fd = 1357 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1358 ASSERT_LE(0, ruleset_fd); 1359 1360 /* Checks unhandled allowed_access. */ 1361 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1362 &tcp_bind_connect, 0)); 1363 EXPECT_EQ(EINVAL, errno); 1364 1365 /* Checks zero access value. */ 1366 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1367 &tcp_denied, 0)); 1368 EXPECT_EQ(ENOMSG, errno); 1369 1370 /* Adds with legitimate values. */ 1371 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1372 &tcp_bind, 0)); 1373 } 1374 1375 TEST_F(mini, tcp_port_overflow) 1376 { 1377 const struct landlock_ruleset_attr ruleset_attr = { 1378 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1379 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1380 }; 1381 const struct landlock_net_port_attr port_max_bind = { 1382 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1383 .port = UINT16_MAX, 1384 }; 1385 const struct landlock_net_port_attr port_max_connect = { 1386 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP, 1387 .port = UINT16_MAX, 1388 }; 1389 const struct landlock_net_port_attr port_overflow1 = { 1390 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1391 .port = UINT16_MAX + 1, 1392 }; 1393 const struct landlock_net_port_attr port_overflow2 = { 1394 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1395 .port = UINT16_MAX + 2, 1396 }; 1397 const struct landlock_net_port_attr port_overflow3 = { 1398 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1399 .port = UINT32_MAX + 1UL, 1400 }; 1401 const struct landlock_net_port_attr port_overflow4 = { 1402 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1403 .port = UINT32_MAX + 2UL, 1404 }; 1405 const struct protocol_variant ipv4_tcp = { 1406 .domain = AF_INET, 1407 .type = SOCK_STREAM, 1408 }; 1409 struct service_fixture srv_denied, srv_max_allowed; 1410 int ruleset_fd; 1411 1412 ASSERT_EQ(0, set_service(&srv_denied, ipv4_tcp, 0)); 1413 1414 /* Be careful to avoid port inconsistencies. */ 1415 srv_max_allowed = srv_denied; 1416 srv_max_allowed.port = port_max_bind.port; 1417 srv_max_allowed.ipv4_addr.sin_port = htons(port_max_bind.port); 1418 1419 ruleset_fd = 1420 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1421 ASSERT_LE(0, ruleset_fd); 1422 1423 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1424 &port_max_bind, 0)); 1425 1426 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1427 &port_overflow1, 0)); 1428 EXPECT_EQ(EINVAL, errno); 1429 1430 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1431 &port_overflow2, 0)); 1432 EXPECT_EQ(EINVAL, errno); 1433 1434 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1435 &port_overflow3, 0)); 1436 EXPECT_EQ(EINVAL, errno); 1437 1438 /* Interleaves with invalid rule additions. */ 1439 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1440 &port_max_connect, 0)); 1441 1442 EXPECT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1443 &port_overflow4, 0)); 1444 EXPECT_EQ(EINVAL, errno); 1445 1446 enforce_ruleset(_metadata, ruleset_fd); 1447 1448 test_bind_and_connect(_metadata, &srv_denied, true, true); 1449 test_bind_and_connect(_metadata, &srv_max_allowed, false, false); 1450 } 1451 1452 FIXTURE(ipv4_tcp) 1453 { 1454 struct service_fixture srv0, srv1; 1455 }; 1456 1457 FIXTURE_SETUP(ipv4_tcp) 1458 { 1459 const struct protocol_variant ipv4_tcp = { 1460 .domain = AF_INET, 1461 .type = SOCK_STREAM, 1462 }; 1463 1464 disable_caps(_metadata); 1465 1466 ASSERT_EQ(0, set_service(&self->srv0, ipv4_tcp, 0)); 1467 ASSERT_EQ(0, set_service(&self->srv1, ipv4_tcp, 1)); 1468 1469 setup_loopback(_metadata); 1470 }; 1471 1472 FIXTURE_TEARDOWN(ipv4_tcp) 1473 { 1474 } 1475 1476 TEST_F(ipv4_tcp, port_endianness) 1477 { 1478 const struct landlock_ruleset_attr ruleset_attr = { 1479 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1480 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1481 }; 1482 const struct landlock_net_port_attr bind_host_endian_p0 = { 1483 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1484 /* Host port format. */ 1485 .port = self->srv0.port, 1486 }; 1487 const struct landlock_net_port_attr connect_big_endian_p0 = { 1488 .allowed_access = LANDLOCK_ACCESS_NET_CONNECT_TCP, 1489 /* Big endian port format. */ 1490 .port = htons(self->srv0.port), 1491 }; 1492 const struct landlock_net_port_attr bind_connect_host_endian_p1 = { 1493 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1494 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1495 /* Host port format. */ 1496 .port = self->srv1.port, 1497 }; 1498 const unsigned int one = 1; 1499 const char little_endian = *(const char *)&one; 1500 int ruleset_fd; 1501 1502 ruleset_fd = 1503 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 1504 ASSERT_LE(0, ruleset_fd); 1505 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1506 &bind_host_endian_p0, 0)); 1507 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1508 &connect_big_endian_p0, 0)); 1509 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1510 &bind_connect_host_endian_p1, 0)); 1511 enforce_ruleset(_metadata, ruleset_fd); 1512 1513 /* No restriction for big endinan CPU. */ 1514 test_bind_and_connect(_metadata, &self->srv0, false, little_endian); 1515 1516 /* No restriction for any CPU. */ 1517 test_bind_and_connect(_metadata, &self->srv1, false, false); 1518 } 1519 1520 TEST_F(ipv4_tcp, with_fs) 1521 { 1522 const struct landlock_ruleset_attr ruleset_attr_fs_net = { 1523 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 1524 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 1525 }; 1526 struct landlock_path_beneath_attr path_beneath = { 1527 .allowed_access = LANDLOCK_ACCESS_FS_READ_DIR, 1528 .parent_fd = -1, 1529 }; 1530 struct landlock_net_port_attr tcp_bind = { 1531 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 1532 .port = self->srv0.port, 1533 }; 1534 int ruleset_fd, bind_fd, dir_fd; 1535 1536 /* Creates ruleset both for filesystem and network access. */ 1537 ruleset_fd = landlock_create_ruleset(&ruleset_attr_fs_net, 1538 sizeof(ruleset_attr_fs_net), 0); 1539 ASSERT_LE(0, ruleset_fd); 1540 1541 /* Adds a filesystem rule. */ 1542 path_beneath.parent_fd = open("/dev", O_PATH | O_DIRECTORY | O_CLOEXEC); 1543 ASSERT_LE(0, path_beneath.parent_fd); 1544 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 1545 &path_beneath, 0)); 1546 EXPECT_EQ(0, close(path_beneath.parent_fd)); 1547 1548 /* Adds a network rule. */ 1549 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1550 &tcp_bind, 0)); 1551 1552 enforce_ruleset(_metadata, ruleset_fd); 1553 EXPECT_EQ(0, close(ruleset_fd)); 1554 1555 /* Tests file access. */ 1556 dir_fd = open("/dev", O_RDONLY); 1557 EXPECT_LE(0, dir_fd); 1558 EXPECT_EQ(0, close(dir_fd)); 1559 1560 dir_fd = open("/", O_RDONLY); 1561 EXPECT_EQ(-1, dir_fd); 1562 EXPECT_EQ(EACCES, errno); 1563 1564 /* Tests port binding. */ 1565 bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 1566 ASSERT_LE(0, bind_fd); 1567 EXPECT_EQ(0, bind_variant(bind_fd, &self->srv0)); 1568 EXPECT_EQ(0, close(bind_fd)); 1569 1570 bind_fd = socket(AF_INET, SOCK_STREAM | SOCK_CLOEXEC, 0); 1571 ASSERT_LE(0, bind_fd); 1572 EXPECT_EQ(-EACCES, bind_variant(bind_fd, &self->srv1)); 1573 } 1574 1575 FIXTURE(port_specific) 1576 { 1577 struct service_fixture srv0; 1578 }; 1579 1580 FIXTURE_VARIANT(port_specific) 1581 { 1582 const enum sandbox_type sandbox; 1583 const struct protocol_variant prot; 1584 }; 1585 1586 /* clang-format off */ 1587 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv4) { 1588 /* clang-format on */ 1589 .sandbox = NO_SANDBOX, 1590 .prot = { 1591 .domain = AF_INET, 1592 .type = SOCK_STREAM, 1593 }, 1594 }; 1595 1596 /* clang-format off */ 1597 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv4) { 1598 /* clang-format on */ 1599 .sandbox = TCP_SANDBOX, 1600 .prot = { 1601 .domain = AF_INET, 1602 .type = SOCK_STREAM, 1603 }, 1604 }; 1605 1606 /* clang-format off */ 1607 FIXTURE_VARIANT_ADD(port_specific, no_sandbox_with_ipv6) { 1608 /* clang-format on */ 1609 .sandbox = NO_SANDBOX, 1610 .prot = { 1611 .domain = AF_INET6, 1612 .type = SOCK_STREAM, 1613 }, 1614 }; 1615 1616 /* clang-format off */ 1617 FIXTURE_VARIANT_ADD(port_specific, sandbox_with_ipv6) { 1618 /* clang-format on */ 1619 .sandbox = TCP_SANDBOX, 1620 .prot = { 1621 .domain = AF_INET6, 1622 .type = SOCK_STREAM, 1623 }, 1624 }; 1625 1626 FIXTURE_SETUP(port_specific) 1627 { 1628 disable_caps(_metadata); 1629 1630 ASSERT_EQ(0, set_service(&self->srv0, variant->prot, 0)); 1631 1632 setup_loopback(_metadata); 1633 }; 1634 1635 FIXTURE_TEARDOWN(port_specific) 1636 { 1637 } 1638 1639 TEST_F(port_specific, bind_connect_zero) 1640 { 1641 int bind_fd, connect_fd, ret; 1642 uint16_t port; 1643 1644 /* Adds a rule layer with bind and connect actions. */ 1645 if (variant->sandbox == TCP_SANDBOX) { 1646 const struct landlock_ruleset_attr ruleset_attr = { 1647 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1648 LANDLOCK_ACCESS_NET_CONNECT_TCP 1649 }; 1650 const struct landlock_net_port_attr tcp_bind_connect_zero = { 1651 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1652 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1653 .port = 0, 1654 }; 1655 int ruleset_fd; 1656 1657 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1658 sizeof(ruleset_attr), 0); 1659 ASSERT_LE(0, ruleset_fd); 1660 1661 /* Checks zero port value on bind and connect actions. */ 1662 EXPECT_EQ(0, 1663 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1664 &tcp_bind_connect_zero, 0)); 1665 1666 enforce_ruleset(_metadata, ruleset_fd); 1667 EXPECT_EQ(0, close(ruleset_fd)); 1668 } 1669 1670 bind_fd = socket_variant(&self->srv0); 1671 ASSERT_LE(0, bind_fd); 1672 1673 connect_fd = socket_variant(&self->srv0); 1674 ASSERT_LE(0, connect_fd); 1675 1676 /* Sets address port to 0 for both protocol families. */ 1677 set_port(&self->srv0, 0); 1678 /* 1679 * Binds on port 0, which selects a random port within 1680 * ip_local_port_range. 1681 */ 1682 ret = bind_variant(bind_fd, &self->srv0); 1683 EXPECT_EQ(0, ret); 1684 1685 EXPECT_EQ(0, listen(bind_fd, backlog)); 1686 1687 /* Connects on port 0. */ 1688 ret = connect_variant(connect_fd, &self->srv0); 1689 EXPECT_EQ(-ECONNREFUSED, ret); 1690 1691 /* Sets binded port for both protocol families. */ 1692 port = get_binded_port(bind_fd, &variant->prot); 1693 EXPECT_NE(0, port); 1694 set_port(&self->srv0, port); 1695 /* Connects on the binded port. */ 1696 ret = connect_variant(connect_fd, &self->srv0); 1697 if (is_restricted(&variant->prot, variant->sandbox)) { 1698 /* Denied by Landlock. */ 1699 EXPECT_EQ(-EACCES, ret); 1700 } else { 1701 EXPECT_EQ(0, ret); 1702 } 1703 1704 EXPECT_EQ(0, close(connect_fd)); 1705 EXPECT_EQ(0, close(bind_fd)); 1706 } 1707 1708 TEST_F(port_specific, bind_connect_1023) 1709 { 1710 int bind_fd, connect_fd, ret; 1711 1712 /* Adds a rule layer with bind and connect actions. */ 1713 if (variant->sandbox == TCP_SANDBOX) { 1714 const struct landlock_ruleset_attr ruleset_attr = { 1715 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP | 1716 LANDLOCK_ACCESS_NET_CONNECT_TCP 1717 }; 1718 /* A rule with port value less than 1024. */ 1719 const struct landlock_net_port_attr tcp_bind_connect_low_range = { 1720 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1721 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1722 .port = 1023, 1723 }; 1724 /* A rule with 1024 port. */ 1725 const struct landlock_net_port_attr tcp_bind_connect = { 1726 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP | 1727 LANDLOCK_ACCESS_NET_CONNECT_TCP, 1728 .port = 1024, 1729 }; 1730 int ruleset_fd; 1731 1732 ruleset_fd = landlock_create_ruleset(&ruleset_attr, 1733 sizeof(ruleset_attr), 0); 1734 ASSERT_LE(0, ruleset_fd); 1735 1736 ASSERT_EQ(0, 1737 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1738 &tcp_bind_connect_low_range, 0)); 1739 ASSERT_EQ(0, 1740 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 1741 &tcp_bind_connect, 0)); 1742 1743 enforce_ruleset(_metadata, ruleset_fd); 1744 EXPECT_EQ(0, close(ruleset_fd)); 1745 } 1746 1747 bind_fd = socket_variant(&self->srv0); 1748 ASSERT_LE(0, bind_fd); 1749 1750 connect_fd = socket_variant(&self->srv0); 1751 ASSERT_LE(0, connect_fd); 1752 1753 /* Sets address port to 1023 for both protocol families. */ 1754 set_port(&self->srv0, 1023); 1755 /* Binds on port 1023. */ 1756 ret = bind_variant(bind_fd, &self->srv0); 1757 /* Denied by the system. */ 1758 EXPECT_EQ(-EACCES, ret); 1759 1760 /* Binds on port 1023. */ 1761 set_cap(_metadata, CAP_NET_BIND_SERVICE); 1762 ret = bind_variant(bind_fd, &self->srv0); 1763 clear_cap(_metadata, CAP_NET_BIND_SERVICE); 1764 EXPECT_EQ(0, ret); 1765 EXPECT_EQ(0, listen(bind_fd, backlog)); 1766 1767 /* Connects on the binded port 1023. */ 1768 ret = connect_variant(connect_fd, &self->srv0); 1769 EXPECT_EQ(0, ret); 1770 1771 EXPECT_EQ(0, close(connect_fd)); 1772 EXPECT_EQ(0, close(bind_fd)); 1773 1774 bind_fd = socket_variant(&self->srv0); 1775 ASSERT_LE(0, bind_fd); 1776 1777 connect_fd = socket_variant(&self->srv0); 1778 ASSERT_LE(0, connect_fd); 1779 1780 /* Sets address port to 1024 for both protocol families. */ 1781 set_port(&self->srv0, 1024); 1782 /* Binds on port 1024. */ 1783 ret = bind_variant(bind_fd, &self->srv0); 1784 EXPECT_EQ(0, ret); 1785 EXPECT_EQ(0, listen(bind_fd, backlog)); 1786 1787 /* Connects on the binded port 1024. */ 1788 ret = connect_variant(connect_fd, &self->srv0); 1789 EXPECT_EQ(0, ret); 1790 1791 EXPECT_EQ(0, close(connect_fd)); 1792 EXPECT_EQ(0, close(bind_fd)); 1793 } 1794 1795 TEST_HARNESS_MAIN 1796