1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Landlock tests - Common user space base 4 * 5 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> 6 * Copyright © 2019-2020 ANSSI 7 */ 8 9 #define _GNU_SOURCE 10 #include <errno.h> 11 #include <fcntl.h> 12 #include <linux/keyctl.h> 13 #include <linux/landlock.h> 14 #include <string.h> 15 #include <sys/prctl.h> 16 #include <sys/socket.h> 17 #include <sys/types.h> 18 19 #include "common.h" 20 21 #ifndef O_PATH 22 #define O_PATH 010000000 23 #endif 24 25 TEST(inconsistent_attr) 26 { 27 const long page_size = sysconf(_SC_PAGESIZE); 28 char *const buf = malloc(page_size + 1); 29 struct landlock_ruleset_attr *const ruleset_attr = (void *)buf; 30 31 ASSERT_NE(NULL, buf); 32 33 /* Checks copy_from_user(). */ 34 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 0, 0)); 35 /* The size if less than sizeof(struct landlock_attr_enforce). */ 36 ASSERT_EQ(EINVAL, errno); 37 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 1, 0)); 38 ASSERT_EQ(EINVAL, errno); 39 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 7, 0)); 40 ASSERT_EQ(EINVAL, errno); 41 42 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 1, 0)); 43 /* The size if less than sizeof(struct landlock_attr_enforce). */ 44 ASSERT_EQ(EFAULT, errno); 45 46 ASSERT_EQ(-1, landlock_create_ruleset( 47 NULL, sizeof(struct landlock_ruleset_attr), 0)); 48 ASSERT_EQ(EFAULT, errno); 49 50 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0)); 51 ASSERT_EQ(E2BIG, errno); 52 53 /* Checks minimal valid attribute size. */ 54 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, 8, 0)); 55 ASSERT_EQ(ENOMSG, errno); 56 ASSERT_EQ(-1, landlock_create_ruleset( 57 ruleset_attr, 58 sizeof(struct landlock_ruleset_attr), 0)); 59 ASSERT_EQ(ENOMSG, errno); 60 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size, 0)); 61 ASSERT_EQ(ENOMSG, errno); 62 63 /* Checks non-zero value. */ 64 buf[page_size - 2] = '.'; 65 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size, 0)); 66 ASSERT_EQ(E2BIG, errno); 67 68 ASSERT_EQ(-1, landlock_create_ruleset(ruleset_attr, page_size + 1, 0)); 69 ASSERT_EQ(E2BIG, errno); 70 71 free(buf); 72 } 73 74 TEST(abi_version) 75 { 76 const struct landlock_ruleset_attr ruleset_attr = { 77 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, 78 }; 79 ASSERT_EQ(11, landlock_create_ruleset(NULL, 0, 80 LANDLOCK_CREATE_RULESET_VERSION)); 81 82 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, 83 LANDLOCK_CREATE_RULESET_VERSION)); 84 ASSERT_EQ(EINVAL, errno); 85 86 ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), 87 LANDLOCK_CREATE_RULESET_VERSION)); 88 ASSERT_EQ(EINVAL, errno); 89 90 ASSERT_EQ(-1, 91 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 92 LANDLOCK_CREATE_RULESET_VERSION)); 93 ASSERT_EQ(EINVAL, errno); 94 95 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, 96 LANDLOCK_CREATE_RULESET_VERSION | 97 1 << 31)); 98 ASSERT_EQ(EINVAL, errno); 99 } 100 101 /* 102 * Old source trees might not have the set of Kselftest fixes related to kernel 103 * UAPI headers. 104 */ 105 #ifndef LANDLOCK_CREATE_RULESET_ERRATA 106 #define LANDLOCK_CREATE_RULESET_ERRATA (1U << 1) 107 #endif 108 109 TEST(errata) 110 { 111 const struct landlock_ruleset_attr ruleset_attr = { 112 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, 113 }; 114 int errata; 115 116 errata = landlock_create_ruleset(NULL, 0, 117 LANDLOCK_CREATE_RULESET_ERRATA); 118 /* The errata bitmask will not be backported to tests. */ 119 ASSERT_LE(0, errata); 120 TH_LOG("errata: 0x%x", errata); 121 122 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, 123 LANDLOCK_CREATE_RULESET_ERRATA)); 124 ASSERT_EQ(EINVAL, errno); 125 126 ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), 127 LANDLOCK_CREATE_RULESET_ERRATA)); 128 ASSERT_EQ(EINVAL, errno); 129 130 ASSERT_EQ(-1, 131 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 132 LANDLOCK_CREATE_RULESET_ERRATA)); 133 ASSERT_EQ(EINVAL, errno); 134 135 ASSERT_EQ(-1, landlock_create_ruleset( 136 NULL, 0, 137 LANDLOCK_CREATE_RULESET_VERSION | 138 LANDLOCK_CREATE_RULESET_ERRATA)); 139 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, 140 LANDLOCK_CREATE_RULESET_ERRATA | 141 1 << 31)); 142 ASSERT_EQ(EINVAL, errno); 143 } 144 145 /* Tests ordering of syscall argument checks. */ 146 TEST(create_ruleset_checks_ordering) 147 { 148 const int last_flag = LANDLOCK_CREATE_RULESET_ERRATA; 149 const int invalid_flag = last_flag << 1; 150 int ruleset_fd; 151 const struct landlock_ruleset_attr ruleset_attr = { 152 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, 153 }; 154 155 /* Checks priority for invalid flags. */ 156 ASSERT_EQ(-1, landlock_create_ruleset(NULL, 0, invalid_flag)); 157 ASSERT_EQ(EINVAL, errno); 158 159 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, invalid_flag)); 160 ASSERT_EQ(EINVAL, errno); 161 162 ASSERT_EQ(-1, landlock_create_ruleset(NULL, sizeof(ruleset_attr), 163 invalid_flag)); 164 ASSERT_EQ(EINVAL, errno); 165 166 ASSERT_EQ(-1, 167 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 168 invalid_flag)); 169 ASSERT_EQ(EINVAL, errno); 170 171 /* Checks too big ruleset_attr size. */ 172 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, -1, 0)); 173 ASSERT_EQ(E2BIG, errno); 174 175 /* Checks too small ruleset_attr size. */ 176 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0, 0)); 177 ASSERT_EQ(EINVAL, errno); 178 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 1, 0)); 179 ASSERT_EQ(EINVAL, errno); 180 181 /* Checks valid call. */ 182 ruleset_fd = 183 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 184 ASSERT_LE(0, ruleset_fd); 185 ASSERT_EQ(0, close(ruleset_fd)); 186 } 187 188 /* Tests ordering of syscall argument checks. */ 189 TEST(add_rule_checks_ordering) 190 { 191 const struct landlock_ruleset_attr ruleset_attr = { 192 .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, 193 }; 194 struct landlock_path_beneath_attr path_beneath_attr = { 195 .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE, 196 .parent_fd = -1, 197 }; 198 const int ruleset_fd = 199 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 200 201 ASSERT_LE(0, ruleset_fd); 202 203 /* Checks invalid flags. */ 204 ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 100)); 205 ASSERT_EQ(EINVAL, errno); 206 207 /* Checks invalid ruleset FD. */ 208 ASSERT_EQ(-1, landlock_add_rule(-1, 0, NULL, 0)); 209 ASSERT_EQ(EBADF, errno); 210 211 /* Checks invalid rule type. */ 212 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, 0, NULL, 0)); 213 ASSERT_EQ(EINVAL, errno); 214 215 /* Checks invalid rule attr. */ 216 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 217 NULL, 0)); 218 ASSERT_EQ(EFAULT, errno); 219 220 /* Checks invalid path_beneath.parent_fd. */ 221 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 222 &path_beneath_attr, 0)); 223 ASSERT_EQ(EBADF, errno); 224 225 /* Checks valid call. */ 226 path_beneath_attr.parent_fd = 227 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); 228 ASSERT_LE(0, path_beneath_attr.parent_fd); 229 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 230 &path_beneath_attr, 0)); 231 ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); 232 ASSERT_EQ(0, close(ruleset_fd)); 233 } 234 235 /* Tests ordering of syscall argument and permission checks. */ 236 TEST(restrict_self_checks_ordering) 237 { 238 const struct landlock_ruleset_attr ruleset_attr = { 239 .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, 240 }; 241 struct landlock_path_beneath_attr path_beneath_attr = { 242 .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE, 243 .parent_fd = -1, 244 }; 245 const int ruleset_fd = 246 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 247 248 ASSERT_LE(0, ruleset_fd); 249 path_beneath_attr.parent_fd = 250 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); 251 ASSERT_LE(0, path_beneath_attr.parent_fd); 252 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 253 &path_beneath_attr, 0)); 254 ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); 255 256 /* Checks unprivileged enforcement without no_new_privs. */ 257 drop_caps(_metadata); 258 /* 259 * The flags validity is checked before the no_new_privs / 260 * CAP_SYS_ADMIN requirement. 261 */ 262 ASSERT_EQ(-1, landlock_restrict_self(-1, -1)); 263 ASSERT_EQ(EINVAL, errno); 264 ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); 265 ASSERT_EQ(EPERM, errno); 266 ASSERT_EQ(-1, landlock_restrict_self(ruleset_fd, 0)); 267 ASSERT_EQ(EPERM, errno); 268 /* 269 * LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS fulfills the no_new_privs / 270 * CAP_SYS_ADMIN requirement but requires a ruleset, so the FD is 271 * checked next. 272 */ 273 ASSERT_EQ(-1, landlock_restrict_self( 274 -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 275 ASSERT_EQ(EBADF, errno); 276 277 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); 278 279 /* Checks invalid flags. */ 280 ASSERT_EQ(-1, landlock_restrict_self(-1, -1)); 281 ASSERT_EQ(EINVAL, errno); 282 283 /* Checks invalid ruleset FD. */ 284 ASSERT_EQ(-1, landlock_restrict_self(-1, 0)); 285 ASSERT_EQ(EBADF, errno); 286 287 /* Checks valid call. */ 288 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); 289 ASSERT_EQ(0, close(ruleset_fd)); 290 } 291 292 TEST(restrict_self_max_layers) 293 { 294 const struct landlock_ruleset_attr ruleset_attr = { 295 .handled_access_fs = LANDLOCK_ACCESS_FS_EXECUTE, 296 }; 297 struct landlock_path_beneath_attr path_beneath_attr = { 298 .allowed_access = LANDLOCK_ACCESS_FS_EXECUTE, 299 .parent_fd = -1, 300 }; 301 const int ruleset_fd = 302 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 303 ASSERT_LE(0, ruleset_fd); 304 305 path_beneath_attr.parent_fd = 306 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); 307 ASSERT_LE(0, path_beneath_attr.parent_fd); 308 ASSERT_EQ(0, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 309 &path_beneath_attr, 0)); 310 ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); 311 312 /* Enforces the maximum number of allowed layers. */ 313 for (int i = 0; i < LANDLOCK_MAX_NUM_LAYERS; i++) 314 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); 315 316 /* Enforces one too many rulesets. */ 317 drop_caps(_metadata); 318 ASSERT_EQ(-1, landlock_restrict_self( 319 ruleset_fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 320 ASSERT_EQ(E2BIG, errno); 321 322 /* Checks that the failed call did not set no_new_privs. */ 323 ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); 324 ASSERT_EQ(0, close(ruleset_fd)); 325 } 326 327 TEST(restrict_self_fd) 328 { 329 int fd; 330 331 fd = open("/dev/null", O_RDONLY | O_CLOEXEC); 332 ASSERT_LE(0, fd); 333 334 EXPECT_EQ(-1, landlock_restrict_self(fd, 0)); 335 EXPECT_EQ(EBADFD, errno); 336 } 337 338 TEST(restrict_self_fd_flags) 339 { 340 int fd; 341 342 fd = open("/dev/null", O_RDONLY | O_CLOEXEC); 343 ASSERT_LE(0, fd); 344 345 /* 346 * LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF accepts -1 but not any file 347 * descriptor. 348 */ 349 EXPECT_EQ(-1, landlock_restrict_self( 350 fd, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); 351 EXPECT_EQ(EBADFD, errno); 352 353 /* LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS requires a ruleset FD. */ 354 EXPECT_EQ(-1, landlock_restrict_self( 355 fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 356 EXPECT_EQ(EBADFD, errno); 357 } 358 359 TEST(restrict_self_flags) 360 { 361 const __u32 last_flag = LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS; 362 363 /* Tests invalid flag combinations. */ 364 365 EXPECT_EQ(-1, landlock_restrict_self(-1, last_flag << 1)); 366 EXPECT_EQ(EINVAL, errno); 367 368 EXPECT_EQ(-1, landlock_restrict_self(-1, -1)); 369 EXPECT_EQ(EINVAL, errno); 370 371 /* Tests valid flag combinations. */ 372 373 EXPECT_EQ(-1, landlock_restrict_self(-1, 0)); 374 EXPECT_EQ(EBADF, errno); 375 376 EXPECT_EQ(-1, landlock_restrict_self( 377 -1, LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF)); 378 EXPECT_EQ(EBADF, errno); 379 380 EXPECT_EQ(-1, 381 landlock_restrict_self( 382 -1, 383 LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF | 384 LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); 385 EXPECT_EQ(EBADF, errno); 386 387 EXPECT_EQ(-1, 388 landlock_restrict_self( 389 -1, 390 LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON | 391 LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); 392 EXPECT_EQ(EBADF, errno); 393 394 EXPECT_EQ(-1, landlock_restrict_self( 395 -1, LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON)); 396 EXPECT_EQ(EBADF, errno); 397 398 EXPECT_EQ(-1, 399 landlock_restrict_self( 400 -1, LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF | 401 LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON)); 402 EXPECT_EQ(EBADF, errno); 403 404 /* LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS requires a ruleset FD. */ 405 406 EXPECT_EQ(-1, landlock_restrict_self( 407 -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 408 EXPECT_EQ(EBADF, errno); 409 410 EXPECT_EQ(-1, landlock_restrict_self( 411 -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF | 412 LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 413 EXPECT_EQ(EBADF, errno); 414 415 /* Tests with an invalid ruleset_fd. */ 416 417 EXPECT_EQ(-1, landlock_restrict_self( 418 -2, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); 419 EXPECT_EQ(EBADF, errno); 420 421 EXPECT_EQ(0, landlock_restrict_self( 422 -1, LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)); 423 } 424 425 TEST(restrict_self_no_new_privs) 426 { 427 const struct landlock_ruleset_attr ruleset_attr = { 428 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, 429 }; 430 const int ruleset_fd = 431 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 432 433 ASSERT_LE(0, ruleset_fd); 434 435 /* 436 * The calling thread does not need CAP_SYS_ADMIN nor an explicit 437 * prctl(2) PR_SET_NO_NEW_PRIVS call. 438 */ 439 drop_caps(_metadata); 440 ASSERT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); 441 442 /* Checks that a failed call does not set no_new_privs. */ 443 EXPECT_EQ(-1, landlock_restrict_self( 444 -1, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 445 EXPECT_EQ(EBADF, errno); 446 EXPECT_EQ(0, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); 447 448 /* Checks that a successful call sets no_new_privs. */ 449 ASSERT_EQ(0, landlock_restrict_self( 450 ruleset_fd, LANDLOCK_RESTRICT_SELF_NO_NEW_PRIVS)); 451 EXPECT_EQ(1, prctl(PR_GET_NO_NEW_PRIVS, 0, 0, 0, 0)); 452 453 EXPECT_EQ(0, close(ruleset_fd)); 454 } 455 456 TEST(ruleset_fd_io) 457 { 458 struct landlock_ruleset_attr ruleset_attr = { 459 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, 460 }; 461 int ruleset_fd; 462 char buf; 463 464 drop_caps(_metadata); 465 ruleset_fd = 466 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 467 ASSERT_LE(0, ruleset_fd); 468 469 ASSERT_EQ(-1, write(ruleset_fd, ".", 1)); 470 ASSERT_EQ(EINVAL, errno); 471 ASSERT_EQ(-1, read(ruleset_fd, &buf, 1)); 472 ASSERT_EQ(EINVAL, errno); 473 474 ASSERT_EQ(0, close(ruleset_fd)); 475 } 476 477 /* Tests enforcement of a ruleset FD transferred through a UNIX socket. */ 478 TEST(ruleset_fd_transfer) 479 { 480 struct landlock_ruleset_attr ruleset_attr = { 481 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 482 }; 483 struct landlock_path_beneath_attr path_beneath_attr = { 484 .allowed_access = LANDLOCK_ACCESS_FS_READ_DIR, 485 }; 486 int ruleset_fd_tx, dir_fd; 487 int socket_fds[2]; 488 pid_t child; 489 int status; 490 491 drop_caps(_metadata); 492 493 /* Creates a test ruleset with a simple rule. */ 494 ruleset_fd_tx = 495 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 496 ASSERT_LE(0, ruleset_fd_tx); 497 path_beneath_attr.parent_fd = 498 open("/tmp", O_PATH | O_NOFOLLOW | O_DIRECTORY | O_CLOEXEC); 499 ASSERT_LE(0, path_beneath_attr.parent_fd); 500 ASSERT_EQ(0, 501 landlock_add_rule(ruleset_fd_tx, LANDLOCK_RULE_PATH_BENEATH, 502 &path_beneath_attr, 0)); 503 ASSERT_EQ(0, close(path_beneath_attr.parent_fd)); 504 505 /* Sends the ruleset FD over a socketpair and then close it. */ 506 ASSERT_EQ(0, socketpair(AF_UNIX, SOCK_STREAM | SOCK_CLOEXEC, 0, 507 socket_fds)); 508 ASSERT_EQ(0, send_fd(socket_fds[0], ruleset_fd_tx)); 509 ASSERT_EQ(0, close(socket_fds[0])); 510 ASSERT_EQ(0, close(ruleset_fd_tx)); 511 512 child = fork(); 513 ASSERT_LE(0, child); 514 if (child == 0) { 515 const int ruleset_fd_rx = recv_fd(socket_fds[1]); 516 517 ASSERT_LE(0, ruleset_fd_rx); 518 ASSERT_EQ(0, close(socket_fds[1])); 519 520 /* Enforces the received ruleset on the child. */ 521 ASSERT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); 522 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd_rx, 0)); 523 ASSERT_EQ(0, close(ruleset_fd_rx)); 524 525 /* Checks that the ruleset enforcement. */ 526 ASSERT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); 527 ASSERT_EQ(EACCES, errno); 528 dir_fd = open("/tmp", O_RDONLY | O_DIRECTORY | O_CLOEXEC); 529 ASSERT_LE(0, dir_fd); 530 ASSERT_EQ(0, close(dir_fd)); 531 _exit(_metadata->exit_code); 532 return; 533 } 534 535 ASSERT_EQ(0, close(socket_fds[1])); 536 537 /* Checks that the parent is unrestricted. */ 538 dir_fd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); 539 ASSERT_LE(0, dir_fd); 540 ASSERT_EQ(0, close(dir_fd)); 541 dir_fd = open("/tmp", O_RDONLY | O_DIRECTORY | O_CLOEXEC); 542 ASSERT_LE(0, dir_fd); 543 ASSERT_EQ(0, close(dir_fd)); 544 545 ASSERT_EQ(child, waitpid(child, &status, 0)); 546 ASSERT_EQ(1, WIFEXITED(status)); 547 ASSERT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 548 } 549 550 TEST(cred_transfer) 551 { 552 struct landlock_ruleset_attr ruleset_attr = { 553 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 554 }; 555 int ruleset_fd, dir_fd; 556 pid_t child; 557 int status; 558 559 drop_caps(_metadata); 560 561 dir_fd = open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC); 562 EXPECT_LE(0, dir_fd); 563 EXPECT_EQ(0, close(dir_fd)); 564 565 /* Denies opening directories. */ 566 ruleset_fd = 567 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 568 ASSERT_LE(0, ruleset_fd); 569 EXPECT_EQ(0, prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); 570 ASSERT_EQ(0, landlock_restrict_self(ruleset_fd, 0)); 571 EXPECT_EQ(0, close(ruleset_fd)); 572 573 /* Checks ruleset enforcement. */ 574 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); 575 EXPECT_EQ(EACCES, errno); 576 577 /* Needed for KEYCTL_SESSION_TO_PARENT permission checks */ 578 EXPECT_NE(-1, syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, NULL, 0, 579 0, 0)) 580 { 581 TH_LOG("Failed to join session keyring: %s", strerror(errno)); 582 } 583 584 child = fork(); 585 ASSERT_LE(0, child); 586 if (child == 0) { 587 /* Checks ruleset enforcement. */ 588 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); 589 EXPECT_EQ(EACCES, errno); 590 591 /* 592 * KEYCTL_SESSION_TO_PARENT is a no-op unless we have a 593 * different session keyring in the child, so make that happen. 594 */ 595 EXPECT_NE(-1, syscall(__NR_keyctl, KEYCTL_JOIN_SESSION_KEYRING, 596 NULL, 0, 0, 0)); 597 598 /* 599 * KEYCTL_SESSION_TO_PARENT installs credentials on the parent 600 * that never go through the cred_prepare hook, this path uses 601 * cred_transfer instead. 602 */ 603 EXPECT_EQ(0, syscall(__NR_keyctl, KEYCTL_SESSION_TO_PARENT, 0, 604 0, 0, 0)); 605 606 /* Re-checks ruleset enforcement. */ 607 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); 608 EXPECT_EQ(EACCES, errno); 609 610 _exit(_metadata->exit_code); 611 return; 612 } 613 614 EXPECT_EQ(child, waitpid(child, &status, 0)); 615 EXPECT_EQ(1, WIFEXITED(status)); 616 EXPECT_EQ(EXIT_SUCCESS, WEXITSTATUS(status)); 617 618 /* Re-checks ruleset enforcement. */ 619 EXPECT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); 620 EXPECT_EQ(EACCES, errno); 621 } 622 623 TEST(useless_quiet_rule_fs) 624 { 625 struct landlock_ruleset_attr ruleset_attr = { 626 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 627 .quiet_access_fs = 0, 628 }; 629 struct landlock_path_beneath_attr path_beneath_attr = { 630 .allowed_access = LANDLOCK_ACCESS_FS_READ_DIR, 631 }; 632 int ruleset_fd, root_fd; 633 634 drop_caps(_metadata); 635 ruleset_fd = 636 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 637 ASSERT_LE(0, ruleset_fd); 638 639 root_fd = open("/", O_PATH | O_CLOEXEC); 640 ASSERT_LE(0, root_fd); 641 path_beneath_attr.parent_fd = root_fd; 642 ASSERT_EQ(-1, landlock_add_rule(ruleset_fd, LANDLOCK_RULE_PATH_BENEATH, 643 &path_beneath_attr, 644 LANDLOCK_ADD_RULE_QUIET)); 645 ASSERT_EQ(EINVAL, errno); 646 647 /* Check that the rule had not been added. */ 648 ASSERT_EQ(0, close(root_fd)); 649 enforce_ruleset(_metadata, ruleset_fd); 650 ASSERT_EQ(0, close(ruleset_fd)); 651 652 ASSERT_EQ(-1, open("/", O_RDONLY | O_DIRECTORY | O_CLOEXEC)); 653 ASSERT_EQ(EACCES, errno); 654 } 655 656 TEST(useless_quiet_rule_net) 657 { 658 struct landlock_ruleset_attr ruleset_attr = { 659 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 660 .quiet_access_net = 0, 661 }; 662 struct landlock_net_port_attr net_port_attr = { 663 .allowed_access = LANDLOCK_ACCESS_NET_BIND_TCP, 664 .port = 1024, 665 }; 666 int ruleset_fd; 667 668 drop_caps(_metadata); 669 ruleset_fd = 670 landlock_create_ruleset(&ruleset_attr, sizeof(ruleset_attr), 0); 671 ASSERT_LE(0, ruleset_fd); 672 673 ASSERT_EQ(-1, 674 landlock_add_rule(ruleset_fd, LANDLOCK_RULE_NET_PORT, 675 &net_port_attr, LANDLOCK_ADD_RULE_QUIET)); 676 ASSERT_EQ(EINVAL, errno); 677 678 ASSERT_EQ(0, close(ruleset_fd)); 679 } 680 681 TEST(invalid_quiet_bits_1) 682 { 683 const struct landlock_ruleset_attr ruleset_attr_fs = { 684 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 685 .quiet_access_fs = LANDLOCK_ACCESS_FS_WRITE_FILE, 686 }; 687 const struct landlock_ruleset_attr ruleset_attr_net = { 688 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 689 .quiet_access_net = LANDLOCK_ACCESS_NET_CONNECT_TCP, 690 }; 691 const struct landlock_ruleset_attr ruleset_attr_scoped = { 692 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, 693 .quiet_scoped = LANDLOCK_SCOPE_SIGNAL, 694 }; 695 696 /* Quiet bit set but not part of the handled mask. */ 697 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_fs, 698 sizeof(ruleset_attr_fs), 0)); 699 ASSERT_EQ(EINVAL, errno); 700 701 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_net, 702 sizeof(ruleset_attr_net), 0)); 703 ASSERT_EQ(EINVAL, errno); 704 705 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_scoped, 706 sizeof(ruleset_attr_scoped), 0)); 707 ASSERT_EQ(EINVAL, errno); 708 } 709 710 TEST(invalid_quiet_bits_2) 711 { 712 const struct landlock_ruleset_attr ruleset_attr_fs = { 713 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_DIR, 714 .quiet_access_fs = 1ULL << 63, 715 }; 716 const struct landlock_ruleset_attr ruleset_attr_net = { 717 .handled_access_net = LANDLOCK_ACCESS_NET_BIND_TCP, 718 .quiet_access_net = 1ULL << 63, 719 }; 720 const struct landlock_ruleset_attr ruleset_attr_scoped = { 721 .scoped = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET, 722 .quiet_scoped = 1ULL << 63, 723 }; 724 725 /* Quiet bit outside of the valid access range. */ 726 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_fs, 727 sizeof(ruleset_attr_fs), 0)); 728 ASSERT_EQ(EINVAL, errno); 729 730 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_net, 731 sizeof(ruleset_attr_net), 0)); 732 ASSERT_EQ(EINVAL, errno); 733 734 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr_scoped, 735 sizeof(ruleset_attr_scoped), 0)); 736 ASSERT_EQ(EINVAL, errno); 737 } 738 739 TEST_HARNESS_MAIN 740