Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'landlock-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux

Pull landlock updates from Mickaël Salaün:
"Some miscellaneous improvements, including new KUnit tests, extended
documentation and boot help, and some cosmetic cleanups.

Additional test changes already went through the net tree"

* tag 'landlock-6.9-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/mic/linux:
samples/landlock: Don't error out if a file path cannot be opened
landlock: Use f_cred in security_file_open() hook
landlock: Rename "ptrace" files to "task"
landlock: Simplify current_check_access_socket()
landlock: Warn once if a Landlock action is requested while disabled
landlock: Extend documentation for kernel support
landlock: Add support for KUnit tests
selftests/landlock: Clean up error logs related to capabilities

+363 -65
+52 -7
Documentation/userspace-api/landlock.rst
··· 19 19 any process, including unprivileged ones, to securely restrict themselves. 20 20 21 21 We can quickly make sure that Landlock is enabled in the running system by 22 - looking for "landlock: Up and running" in kernel logs (as root): ``dmesg | grep 23 - landlock || journalctl -kg landlock`` . Developers can also easily check for 24 - Landlock support with a :ref:`related system call <landlock_abi_versions>`. If 25 - Landlock is not currently supported, we need to :ref:`configure the kernel 26 - appropriately <kernel_support>`. 22 + looking for "landlock: Up and running" in kernel logs (as root): 23 + ``dmesg | grep landlock || journalctl -kb -g landlock`` . 24 + Developers can also easily check for Landlock support with a 25 + :ref:`related system call <landlock_abi_versions>`. 26 + If Landlock is not currently supported, we need to 27 + :ref:`configure the kernel appropriately <kernel_support>`. 27 28 28 29 Landlock rules 29 30 ============== ··· 500 499 Kernel support 501 500 ============== 502 501 502 + Build time configuration 503 + ------------------------ 504 + 503 505 Landlock was first introduced in Linux 5.13 but it must be configured at build 504 506 time with ``CONFIG_SECURITY_LANDLOCK=y``. Landlock must also be enabled at boot 505 507 time as the other security modules. The list of security modules enabled by ··· 511 507 potentially useful security modules for the running system (see the 512 508 ``CONFIG_LSM`` help). 513 509 510 + Boot time configuration 511 + ----------------------- 512 + 514 513 If the running kernel does not have ``landlock`` in ``CONFIG_LSM``, then we can 515 - still enable it by adding ``lsm=landlock,[...]`` to 516 - Documentation/admin-guide/kernel-parameters.rst thanks to the bootloader 514 + enable Landlock by adding ``lsm=landlock,[...]`` to 515 + Documentation/admin-guide/kernel-parameters.rst in the boot loader 517 516 configuration. 517 + 518 + For example, if the current built-in configuration is: 519 + 520 + .. code-block:: console 521 + 522 + $ zgrep -h "^CONFIG_LSM=" "/boot/config-$(uname -r)" /proc/config.gz 2>/dev/null 523 + CONFIG_LSM="lockdown,yama,integrity,apparmor" 524 + 525 + ...and if the cmdline doesn't contain ``landlock`` either: 526 + 527 + .. code-block:: console 528 + 529 + $ sed -n 's/.*\(\<lsm=\S\+\).*/\1/p' /proc/cmdline 530 + lsm=lockdown,yama,integrity,apparmor 531 + 532 + ...we should configure the boot loader to set a cmdline extending the ``lsm`` 533 + list with the ``landlock,`` prefix:: 534 + 535 + lsm=landlock,lockdown,yama,integrity,apparmor 536 + 537 + After a reboot, we can check that Landlock is up and running by looking at 538 + kernel logs: 539 + 540 + .. code-block:: console 541 + 542 + # dmesg | grep landlock || journalctl -kb -g landlock 543 + [ 0.000000] Command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor 544 + [ 0.000000] Kernel command line: [...] lsm=landlock,lockdown,yama,integrity,apparmor 545 + [ 0.000000] LSM: initializing lsm=lockdown,capability,landlock,yama,integrity,apparmor 546 + [ 0.000000] landlock: Up and running. 547 + 548 + The kernel may be configured at build time to always load the ``lockdown`` and 549 + ``capability`` LSMs. In that case, these LSMs will appear at the beginning of 550 + the ``LSM: initializing`` log line as well, even if they are not configured in 551 + the boot loader. 552 + 553 + Network support 554 + --------------- 518 555 519 556 To be able to explicitly allow TCP operations (e.g., adding a network rule with 520 557 ``LANDLOCK_ACCESS_NET_BIND_TCP``), the kernel must support TCP
+8 -5
samples/landlock/sandboxer.c
··· 1 1 // SPDX-License-Identifier: BSD-3-Clause 2 2 /* 3 - * Simple Landlock sandbox manager able to launch a process restricted by a 4 - * user-defined filesystem access control policy. 3 + * Simple Landlock sandbox manager able to execute a process restricted by 4 + * user-defined file system and network access control policies. 5 5 * 6 6 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> 7 7 * Copyright © 2020 ANSSI ··· 120 120 if (path_beneath.parent_fd < 0) { 121 121 fprintf(stderr, "Failed to open \"%s\": %s\n", 122 122 path_list[i], strerror(errno)); 123 - goto out_free_name; 123 + continue; 124 124 } 125 125 if (fstat(path_beneath.parent_fd, &statbuf)) { 126 + fprintf(stderr, "Failed to stat \"%s\": %s\n", 127 + path_list[i], strerror(errno)); 126 128 close(path_beneath.parent_fd); 127 129 goto out_free_name; 128 130 } ··· 229 227 ENV_FS_RO_NAME, ENV_FS_RW_NAME, ENV_TCP_BIND_NAME, 230 228 ENV_TCP_CONNECT_NAME, argv[0]); 231 229 fprintf(stderr, 232 - "Launch a command in a restricted environment.\n\n"); 230 + "Execute a command in a restricted environment.\n\n"); 233 231 fprintf(stderr, 234 232 "Environment variables containing paths and ports " 235 233 "each separated by a colon:\n"); ··· 250 248 ENV_TCP_CONNECT_NAME); 251 249 fprintf(stderr, 252 250 "\nexample:\n" 253 - "%s=\"/bin:/lib:/usr:/proc:/etc:/dev/urandom\" " 251 + "%s=\"${PATH}:/lib:/usr:/proc:/etc:/dev/urandom\" " 254 252 "%s=\"/dev/null:/dev/full:/dev/zero:/dev/pts:/tmp\" " 255 253 "%s=\"9418\" " 256 254 "%s=\"80:443\" " ··· 385 383 386 384 cmd_path = argv[1]; 387 385 cmd_argv = argv + 1; 386 + fprintf(stderr, "Executing the sandboxed command...\n"); 388 387 execvpe(cmd_path, cmd_argv, envp); 389 388 fprintf(stderr, "Failed to execute \"%s\": %s\n", cmd_path, 390 389 strerror(errno));
+4
security/landlock/.kunitconfig
··· 1 + CONFIG_KUNIT=y 2 + CONFIG_SECURITY=y 3 + CONFIG_SECURITY_LANDLOCK=y 4 + CONFIG_SECURITY_LANDLOCK_KUNIT_TEST=y
+15
security/landlock/Kconfig
··· 20 20 If you are unsure how to answer this question, answer N. Otherwise, 21 21 you should also prepend "landlock," to the content of CONFIG_LSM to 22 22 enable Landlock at boot time. 23 + 24 + config SECURITY_LANDLOCK_KUNIT_TEST 25 + bool "KUnit tests for Landlock" if !KUNIT_ALL_TESTS 26 + depends on KUNIT=y 27 + depends on SECURITY_LANDLOCK 28 + default KUNIT_ALL_TESTS 29 + help 30 + Build KUnit tests for Landlock. 31 + 32 + See the KUnit documentation in Documentation/dev-tools/kunit 33 + 34 + Run all KUnit tests for Landlock with: 35 + ./tools/testing/kunit/kunit.py run --kunitconfig security/landlock 36 + 37 + If you are unsure how to answer this question, answer N.
+1 -1
security/landlock/Makefile
··· 1 1 obj-$(CONFIG_SECURITY_LANDLOCK) := landlock.o 2 2 3 3 landlock-y := setup.o syscalls.o object.o ruleset.o \ 4 - cred.o ptrace.o fs.o 4 + cred.o task.o fs.o 5 5 6 6 landlock-$(CONFIG_INET) += net.o
+2
security/landlock/common.h
··· 17 17 18 18 #define pr_fmt(fmt) LANDLOCK_NAME ": " fmt 19 19 20 + #define BIT_INDEX(bit) HWEIGHT(bit - 1) 21 + 20 22 #endif /* _SECURITY_LANDLOCK_COMMON_H */
+245 -7
security/landlock/fs.c
··· 7 7 * Copyright © 2021-2022 Microsoft Corporation 8 8 */ 9 9 10 + #include <kunit/test.h> 10 11 #include <linux/atomic.h> 11 12 #include <linux/bitops.h> 12 13 #include <linux/bits.h> ··· 248 247 LANDLOCK_ACCESS_FS_INITIALLY_DENIED; 249 248 } 250 249 251 - static const struct landlock_ruleset *get_current_fs_domain(void) 250 + static const struct landlock_ruleset * 251 + get_fs_domain(const struct landlock_ruleset *const domain) 252 252 { 253 - const struct landlock_ruleset *const dom = 254 - landlock_get_current_domain(); 255 - 256 - if (!dom || !get_raw_handled_fs_accesses(dom)) 253 + if (!domain || !get_raw_handled_fs_accesses(domain)) 257 254 return NULL; 258 255 259 - return dom; 256 + return domain; 257 + } 258 + 259 + static const struct landlock_ruleset *get_current_fs_domain(void) 260 + { 261 + return get_fs_domain(landlock_get_current_domain()); 260 262 } 261 263 262 264 /* ··· 315 311 return true; 316 312 } 317 313 314 + #define NMA_TRUE(...) KUNIT_EXPECT_TRUE(test, no_more_access(__VA_ARGS__)) 315 + #define NMA_FALSE(...) KUNIT_EXPECT_FALSE(test, no_more_access(__VA_ARGS__)) 316 + 317 + #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 318 + 319 + static void test_no_more_access(struct kunit *const test) 320 + { 321 + const layer_mask_t rx0[LANDLOCK_NUM_ACCESS_FS] = { 322 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0), 323 + [BIT_INDEX(LANDLOCK_ACCESS_FS_READ_FILE)] = BIT_ULL(0), 324 + }; 325 + const layer_mask_t mx0[LANDLOCK_NUM_ACCESS_FS] = { 326 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0), 327 + [BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_REG)] = BIT_ULL(0), 328 + }; 329 + const layer_mask_t x0[LANDLOCK_NUM_ACCESS_FS] = { 330 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0), 331 + }; 332 + const layer_mask_t x1[LANDLOCK_NUM_ACCESS_FS] = { 333 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(1), 334 + }; 335 + const layer_mask_t x01[LANDLOCK_NUM_ACCESS_FS] = { 336 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0) | 337 + BIT_ULL(1), 338 + }; 339 + const layer_mask_t allows_all[LANDLOCK_NUM_ACCESS_FS] = {}; 340 + 341 + /* Checks without restriction. */ 342 + NMA_TRUE(&x0, &allows_all, false, &allows_all, NULL, false); 343 + NMA_TRUE(&allows_all, &x0, false, &allows_all, NULL, false); 344 + NMA_FALSE(&x0, &x0, false, &allows_all, NULL, false); 345 + 346 + /* 347 + * Checks that we can only refer a file if no more access could be 348 + * inherited. 349 + */ 350 + NMA_TRUE(&x0, &x0, false, &rx0, NULL, false); 351 + NMA_TRUE(&rx0, &rx0, false, &rx0, NULL, false); 352 + NMA_FALSE(&rx0, &rx0, false, &x0, NULL, false); 353 + NMA_FALSE(&rx0, &rx0, false, &x1, NULL, false); 354 + 355 + /* Checks allowed referring with different nested domains. */ 356 + NMA_TRUE(&x0, &x1, false, &x0, NULL, false); 357 + NMA_TRUE(&x1, &x0, false, &x0, NULL, false); 358 + NMA_TRUE(&x0, &x01, false, &x0, NULL, false); 359 + NMA_TRUE(&x0, &x01, false, &rx0, NULL, false); 360 + NMA_TRUE(&x01, &x0, false, &x0, NULL, false); 361 + NMA_TRUE(&x01, &x0, false, &rx0, NULL, false); 362 + NMA_FALSE(&x01, &x01, false, &x0, NULL, false); 363 + 364 + /* Checks that file access rights are also enforced for a directory. */ 365 + NMA_FALSE(&rx0, &rx0, true, &x0, NULL, false); 366 + 367 + /* Checks that directory access rights don't impact file referring... */ 368 + NMA_TRUE(&mx0, &mx0, false, &x0, NULL, false); 369 + /* ...but only directory referring. */ 370 + NMA_FALSE(&mx0, &mx0, true, &x0, NULL, false); 371 + 372 + /* Checks directory exchange. */ 373 + NMA_TRUE(&mx0, &mx0, true, &mx0, &mx0, true); 374 + NMA_TRUE(&mx0, &mx0, true, &mx0, &x0, true); 375 + NMA_FALSE(&mx0, &mx0, true, &x0, &mx0, true); 376 + NMA_FALSE(&mx0, &mx0, true, &x0, &x0, true); 377 + NMA_FALSE(&mx0, &mx0, true, &x1, &x1, true); 378 + 379 + /* Checks file exchange with directory access rights... */ 380 + NMA_TRUE(&mx0, &mx0, false, &mx0, &mx0, false); 381 + NMA_TRUE(&mx0, &mx0, false, &mx0, &x0, false); 382 + NMA_TRUE(&mx0, &mx0, false, &x0, &mx0, false); 383 + NMA_TRUE(&mx0, &mx0, false, &x0, &x0, false); 384 + /* ...and with file access rights. */ 385 + NMA_TRUE(&rx0, &rx0, false, &rx0, &rx0, false); 386 + NMA_TRUE(&rx0, &rx0, false, &rx0, &x0, false); 387 + NMA_FALSE(&rx0, &rx0, false, &x0, &rx0, false); 388 + NMA_FALSE(&rx0, &rx0, false, &x0, &x0, false); 389 + NMA_FALSE(&rx0, &rx0, false, &x1, &x1, false); 390 + 391 + /* 392 + * Allowing the following requests should not be a security risk 393 + * because domain 0 denies execute access, and domain 1 is always 394 + * nested with domain 0. However, adding an exception for this case 395 + * would mean to check all nested domains to make sure none can get 396 + * more privileges (e.g. processes only sandboxed by domain 0). 397 + * Moreover, this behavior (i.e. composition of N domains) could then 398 + * be inconsistent compared to domain 1's ruleset alone (e.g. it might 399 + * be denied to link/rename with domain 1's ruleset, whereas it would 400 + * be allowed if nested on top of domain 0). Another drawback would be 401 + * to create a cover channel that could enable sandboxed processes to 402 + * infer most of the filesystem restrictions from their domain. To 403 + * make it simple, efficient, safe, and more consistent, this case is 404 + * always denied. 405 + */ 406 + NMA_FALSE(&x1, &x1, false, &x0, NULL, false); 407 + NMA_FALSE(&x1, &x1, false, &rx0, NULL, false); 408 + NMA_FALSE(&x1, &x1, true, &x0, NULL, false); 409 + NMA_FALSE(&x1, &x1, true, &rx0, NULL, false); 410 + 411 + /* Checks the same case of exclusive domains with a file... */ 412 + NMA_TRUE(&x1, &x1, false, &x01, NULL, false); 413 + NMA_FALSE(&x1, &x1, false, &x01, &x0, false); 414 + NMA_FALSE(&x1, &x1, false, &x01, &x01, false); 415 + NMA_FALSE(&x1, &x1, false, &x0, &x0, false); 416 + /* ...and with a directory. */ 417 + NMA_FALSE(&x1, &x1, false, &x0, &x0, true); 418 + NMA_FALSE(&x1, &x1, true, &x0, &x0, false); 419 + NMA_FALSE(&x1, &x1, true, &x0, &x0, true); 420 + } 421 + 422 + #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */ 423 + 424 + #undef NMA_TRUE 425 + #undef NMA_FALSE 426 + 318 427 /* 319 428 * Removes @layer_masks accesses that are not requested. 320 429 * ··· 447 330 (*layer_masks)[access_bit] = 0; 448 331 return !memchr_inv(layer_masks, 0, sizeof(*layer_masks)); 449 332 } 333 + 334 + #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 335 + 336 + static void test_scope_to_request_with_exec_none(struct kunit *const test) 337 + { 338 + /* Allows everything. */ 339 + layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; 340 + 341 + /* Checks and scopes with execute. */ 342 + KUNIT_EXPECT_TRUE(test, scope_to_request(LANDLOCK_ACCESS_FS_EXECUTE, 343 + &layer_masks)); 344 + KUNIT_EXPECT_EQ(test, 0, 345 + layer_masks[BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)]); 346 + KUNIT_EXPECT_EQ(test, 0, 347 + layer_masks[BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)]); 348 + } 349 + 350 + static void test_scope_to_request_with_exec_some(struct kunit *const test) 351 + { 352 + /* Denies execute and write. */ 353 + layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = { 354 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0), 355 + [BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)] = BIT_ULL(1), 356 + }; 357 + 358 + /* Checks and scopes with execute. */ 359 + KUNIT_EXPECT_FALSE(test, scope_to_request(LANDLOCK_ACCESS_FS_EXECUTE, 360 + &layer_masks)); 361 + KUNIT_EXPECT_EQ(test, BIT_ULL(0), 362 + layer_masks[BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)]); 363 + KUNIT_EXPECT_EQ(test, 0, 364 + layer_masks[BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)]); 365 + } 366 + 367 + static void test_scope_to_request_without_access(struct kunit *const test) 368 + { 369 + /* Denies execute and write. */ 370 + layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = { 371 + [BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = BIT_ULL(0), 372 + [BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)] = BIT_ULL(1), 373 + }; 374 + 375 + /* Checks and scopes without access request. */ 376 + KUNIT_EXPECT_TRUE(test, scope_to_request(0, &layer_masks)); 377 + KUNIT_EXPECT_EQ(test, 0, 378 + layer_masks[BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)]); 379 + KUNIT_EXPECT_EQ(test, 0, 380 + layer_masks[BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)]); 381 + } 382 + 383 + #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */ 450 384 451 385 /* 452 386 * Returns true if there is at least one access right different than ··· 521 353 } 522 354 return false; 523 355 } 356 + 357 + #define IE_TRUE(...) KUNIT_EXPECT_TRUE(test, is_eacces(__VA_ARGS__)) 358 + #define IE_FALSE(...) KUNIT_EXPECT_FALSE(test, is_eacces(__VA_ARGS__)) 359 + 360 + #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 361 + 362 + static void test_is_eacces_with_none(struct kunit *const test) 363 + { 364 + const layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; 365 + 366 + IE_FALSE(&layer_masks, 0); 367 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_REFER); 368 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_EXECUTE); 369 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_WRITE_FILE); 370 + } 371 + 372 + static void test_is_eacces_with_refer(struct kunit *const test) 373 + { 374 + const layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = { 375 + [BIT_INDEX(LANDLOCK_ACCESS_FS_REFER)] = BIT_ULL(0), 376 + }; 377 + 378 + IE_FALSE(&layer_masks, 0); 379 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_REFER); 380 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_EXECUTE); 381 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_WRITE_FILE); 382 + } 383 + 384 + static void test_is_eacces_with_write(struct kunit *const test) 385 + { 386 + const layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = { 387 + [BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)] = BIT_ULL(0), 388 + }; 389 + 390 + IE_FALSE(&layer_masks, 0); 391 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_REFER); 392 + IE_FALSE(&layer_masks, LANDLOCK_ACCESS_FS_EXECUTE); 393 + 394 + IE_TRUE(&layer_masks, LANDLOCK_ACCESS_FS_WRITE_FILE); 395 + } 396 + 397 + #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */ 398 + 399 + #undef IE_TRUE 400 + #undef IE_FALSE 524 401 525 402 /** 526 403 * is_access_to_paths_allowed - Check accesses for requests with a common path ··· 1337 1124 layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_FS] = {}; 1338 1125 access_mask_t open_access_request, full_access_request, allowed_access; 1339 1126 const access_mask_t optional_access = LANDLOCK_ACCESS_FS_TRUNCATE; 1340 - const struct landlock_ruleset *const dom = get_current_fs_domain(); 1127 + const struct landlock_ruleset *const dom = 1128 + get_fs_domain(landlock_cred(file->f_cred)->domain); 1341 1129 1342 1130 if (!dom) 1343 1131 return 0; ··· 1439 1225 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), 1440 1226 &landlock_lsmid); 1441 1227 } 1228 + 1229 + #ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST 1230 + 1231 + /* clang-format off */ 1232 + static struct kunit_case test_cases[] = { 1233 + KUNIT_CASE(test_no_more_access), 1234 + KUNIT_CASE(test_scope_to_request_with_exec_none), 1235 + KUNIT_CASE(test_scope_to_request_with_exec_some), 1236 + KUNIT_CASE(test_scope_to_request_without_access), 1237 + KUNIT_CASE(test_is_eacces_with_none), 1238 + KUNIT_CASE(test_is_eacces_with_refer), 1239 + KUNIT_CASE(test_is_eacces_with_write), 1240 + {} 1241 + }; 1242 + /* clang-format on */ 1243 + 1244 + static struct kunit_suite test_suite = { 1245 + .name = "landlock_fs", 1246 + .test_cases = test_cases, 1247 + }; 1248 + 1249 + kunit_test_suite(test_suite); 1250 + 1251 + #endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
+3 -4
security/landlock/net.c
··· 64 64 static int current_check_access_socket(struct socket *const sock, 65 65 struct sockaddr *const address, 66 66 const int addrlen, 67 - const access_mask_t access_request) 67 + access_mask_t access_request) 68 68 { 69 69 __be16 port; 70 70 layer_mask_t layer_masks[LANDLOCK_NUM_ACCESS_NET] = {}; 71 71 const struct landlock_rule *rule; 72 - access_mask_t handled_access; 73 72 struct landlock_id id = { 74 73 .type = LANDLOCK_KEY_NET_PORT, 75 74 }; ··· 163 164 BUILD_BUG_ON(sizeof(port) > sizeof(id.key.data)); 164 165 165 166 rule = landlock_find_rule(dom, id); 166 - handled_access = landlock_init_layer_masks( 167 + access_request = landlock_init_layer_masks( 167 168 dom, access_request, &layer_masks, LANDLOCK_KEY_NET_PORT); 168 - if (landlock_unmask_layers(rule, handled_access, &layer_masks, 169 + if (landlock_unmask_layers(rule, access_request, &layer_masks, 169 170 ARRAY_SIZE(layer_masks))) 170 171 return 0; 171 172
+2 -2
security/landlock/ptrace.c security/landlock/task.c
··· 16 16 17 17 #include "common.h" 18 18 #include "cred.h" 19 - #include "ptrace.h" 20 19 #include "ruleset.h" 21 20 #include "setup.h" 21 + #include "task.h" 22 22 23 23 /** 24 24 * domain_scope_le - Checks domain ordering for scoped ptrace ··· 113 113 LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme), 114 114 }; 115 115 116 - __init void landlock_add_ptrace_hooks(void) 116 + __init void landlock_add_task_hooks(void) 117 117 { 118 118 security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks), 119 119 &landlock_lsmid);
+4 -4
security/landlock/ptrace.h security/landlock/task.h
··· 6 6 * Copyright © 2019 ANSSI 7 7 */ 8 8 9 - #ifndef _SECURITY_LANDLOCK_PTRACE_H 10 - #define _SECURITY_LANDLOCK_PTRACE_H 9 + #ifndef _SECURITY_LANDLOCK_TASK_H 10 + #define _SECURITY_LANDLOCK_TASK_H 11 11 12 - __init void landlock_add_ptrace_hooks(void); 12 + __init void landlock_add_task_hooks(void); 13 13 14 - #endif /* _SECURITY_LANDLOCK_PTRACE_H */ 14 + #endif /* _SECURITY_LANDLOCK_TASK_H */
+2 -2
security/landlock/setup.c
··· 14 14 #include "cred.h" 15 15 #include "fs.h" 16 16 #include "net.h" 17 - #include "ptrace.h" 18 17 #include "setup.h" 18 + #include "task.h" 19 19 20 20 bool landlock_initialized __ro_after_init = false; 21 21 ··· 34 34 static int __init landlock_init(void) 35 35 { 36 36 landlock_add_cred_hooks(); 37 - landlock_add_ptrace_hooks(); 37 + landlock_add_task_hooks(); 38 38 landlock_add_fs_hooks(); 39 39 landlock_add_net_hooks(); 40 40 landlock_initialized = true;
+15 -3
security/landlock/syscalls.c
··· 33 33 #include "ruleset.h" 34 34 #include "setup.h" 35 35 36 + static bool is_initialized(void) 37 + { 38 + if (likely(landlock_initialized)) 39 + return true; 40 + 41 + pr_warn_once( 42 + "Disabled but requested by user space. " 43 + "You should enable Landlock at boot time: " 44 + "https://docs.kernel.org/userspace-api/landlock.html#boot-time-configuration\n"); 45 + return false; 46 + } 47 + 36 48 /** 37 49 * copy_min_struct_from_user - Safe future-proof argument copying 38 50 * ··· 185 173 /* Build-time checks. */ 186 174 build_check_abi(); 187 175 188 - if (!landlock_initialized) 176 + if (!is_initialized()) 189 177 return -EOPNOTSUPP; 190 178 191 179 if (flags) { ··· 410 398 struct landlock_ruleset *ruleset; 411 399 int err; 412 400 413 - if (!landlock_initialized) 401 + if (!is_initialized()) 414 402 return -EOPNOTSUPP; 415 403 416 404 /* No flag for now. */ ··· 470 458 struct landlock_cred_security *new_llcred; 471 459 int err; 472 460 473 - if (!landlock_initialized) 461 + if (!is_initialized()) 474 462 return -EOPNOTSUPP; 475 463 476 464 /*
+1
tools/testing/kunit/configs/all_tests.config
··· 43 43 44 44 CONFIG_SECURITY=y 45 45 CONFIG_SECURITY_APPARMOR=y 46 + CONFIG_SECURITY_LANDLOCK=y 46 47 47 48 CONFIG_SOUND=y 48 49 CONFIG_SND=y
+9 -30
tools/testing/selftests/landlock/common.h
··· 74 74 EXPECT_EQ(0, cap_set_secbits(noroot)); 75 75 76 76 cap_p = cap_get_proc(); 77 - EXPECT_NE(NULL, cap_p) 78 - { 79 - TH_LOG("Failed to cap_get_proc: %s", strerror(errno)); 80 - } 81 - EXPECT_NE(-1, cap_clear(cap_p)) 82 - { 83 - TH_LOG("Failed to cap_clear: %s", strerror(errno)); 84 - } 77 + EXPECT_NE(NULL, cap_p); 78 + EXPECT_NE(-1, cap_clear(cap_p)); 85 79 if (!drop_all) { 86 80 EXPECT_NE(-1, cap_set_flag(cap_p, CAP_PERMITTED, 87 - ARRAY_SIZE(caps), caps, CAP_SET)) 88 - { 89 - TH_LOG("Failed to cap_set_flag: %s", strerror(errno)); 90 - } 81 + ARRAY_SIZE(caps), caps, CAP_SET)); 91 82 } 92 83 93 84 /* Automatically resets ambient capabilities. */ 94 85 EXPECT_NE(-1, cap_set_proc(cap_p)) 95 86 { 96 - TH_LOG("Failed to cap_set_proc: %s", strerror(errno)); 87 + TH_LOG("Failed to set capabilities: %s", strerror(errno)); 97 88 } 98 - EXPECT_NE(-1, cap_free(cap_p)) 99 - { 100 - TH_LOG("Failed to cap_free: %s", strerror(errno)); 101 - } 89 + EXPECT_NE(-1, cap_free(cap_p)); 102 90 103 91 /* Quickly checks that ambient capabilities are cleared. */ 104 92 EXPECT_NE(-1, cap_get_ambient(caps[0])); ··· 110 122 cap_t cap_p; 111 123 112 124 cap_p = cap_get_proc(); 113 - EXPECT_NE(NULL, cap_p) 114 - { 115 - TH_LOG("Failed to cap_get_proc: %s", strerror(errno)); 116 - } 117 - EXPECT_NE(-1, cap_set_flag(cap_p, flag, 1, &cap, value)) 118 - { 119 - TH_LOG("Failed to cap_set_flag: %s", strerror(errno)); 120 - } 125 + EXPECT_NE(NULL, cap_p); 126 + EXPECT_NE(-1, cap_set_flag(cap_p, flag, 1, &cap, value)); 121 127 EXPECT_NE(-1, cap_set_proc(cap_p)) 122 128 { 123 - TH_LOG("Failed to cap_set_proc: %s", strerror(errno)); 129 + TH_LOG("Failed to set capability %d: %s", cap, strerror(errno)); 124 130 } 125 - EXPECT_NE(-1, cap_free(cap_p)) 126 - { 127 - TH_LOG("Failed to cap_free: %s", strerror(errno)); 128 - } 131 + EXPECT_NE(-1, cap_free(cap_p)); 129 132 } 130 133 131 134 static void __maybe_unused set_cap(struct __test_metadata *const _metadata,