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