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.

landlock: Add LANDLOCK_RESTRICT_SELF_LOG_*_EXEC_* flags

Most of the time we want to log denied access because they should not
happen and such information helps diagnose issues. However, when
sandboxing processes that we know will try to access denied resources
(e.g. unknown, bogus, or malicious binary), we might want to not log
related access requests that might fill up logs.

By default, denied requests are logged until the task call execve(2).

If the LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF flag is set, denied
requests will not be logged for the same executed file.

If the LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON flag is set, denied
requests from after an execve(2) call will be logged.

The rationale is that a program should know its own behavior, but not
necessarily the behavior of other programs.

Because LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF is set for a specific
Landlock domain, it makes it possible to selectively mask some access
requests that would be logged by a parent domain, which might be handy
for unprivileged processes to limit logs. However, system
administrators should still use the audit filtering mechanism. There is
intentionally no audit nor sysctl configuration to re-enable these logs.
This is delegated to the user space program.

Increment the Landlock ABI version to reflect this interface change.

Cc: Günther Noack <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Link: https://lore.kernel.org/r/20250320190717.2287696-18-mic@digikod.net
[mic: Rename variables and fix __maybe_unused]
Signed-off-by: Mickaël Salaün <mic@digikod.net>

+85 -13
+21
include/uapi/linux/landlock.h
··· 4 4 * 5 5 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net> 6 6 * Copyright © 2018-2020 ANSSI 7 + * Copyright © 2021-2025 Microsoft Corporation 7 8 */ 8 9 9 10 #ifndef _UAPI_LINUX_LANDLOCK_H ··· 63 62 /* clang-format off */ 64 63 #define LANDLOCK_CREATE_RULESET_VERSION (1U << 0) 65 64 #define LANDLOCK_CREATE_RULESET_ERRATA (1U << 1) 65 + /* clang-format on */ 66 + 67 + /* 68 + * sys_landlock_restrict_self() flags: 69 + * 70 + * - %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF: Do not create any log related to the 71 + * enforced restrictions. This should only be set by tools launching unknown 72 + * or untrusted programs (e.g. a sandbox tool, container runtime, system 73 + * service manager). Because programs sandboxing themselves should fix any 74 + * denied access, they should not set this flag to be aware of potential 75 + * issues reported by system's logs (i.e. audit). 76 + * - %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON: Explicitly ask to continue 77 + * logging denied access requests even after an :manpage:`execve(2)` call. 78 + * This flag should only be set if all the programs than can legitimately be 79 + * executed will not try to request a denied access (which could spam audit 80 + * logs). 81 + */ 82 + /* clang-format off */ 83 + #define LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF (1U << 0) 84 + #define LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON (1U << 1) 66 85 /* clang-format on */ 67 86 68 87 /**
+13 -3
security/landlock/audit.c
··· 422 422 get_hierarchy(subject->domain, youngest_layer); 423 423 } 424 424 425 + if (READ_ONCE(youngest_denied->log_status) == LANDLOCK_LOG_DISABLED) 426 + return; 427 + 425 428 /* 426 429 * Consistently keeps track of the number of denied access requests 427 430 * even if audit is currently disabled, or if audit rules currently ··· 436 433 if (!audit_enabled) 437 434 return; 438 435 439 - /* Ignores denials after an execution. */ 440 - if (!(subject->domain_exec & (1 << youngest_layer))) 441 - return; 436 + /* Checks if the current exec was restricting itself. */ 437 + if (subject->domain_exec & (1 << youngest_layer)) { 438 + /* Ignores denials for the same execution. */ 439 + if (!youngest_denied->log_same_exec) 440 + return; 441 + } else { 442 + /* Ignores denials after a new execution. */ 443 + if (!youngest_denied->log_new_exec) 444 + return; 445 + } 442 446 443 447 /* Uses consistent allocation flags wrt common_lsm_audit(). */ 444 448 ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
+2
security/landlock/domain.c
··· 127 127 hierarchy->details = details; 128 128 hierarchy->id = landlock_get_id_range(1); 129 129 hierarchy->log_status = LANDLOCK_LOG_PENDING; 130 + hierarchy->log_same_exec = true; 131 + hierarchy->log_new_exec = false; 130 132 atomic64_set(&hierarchy->num_denials, 0); 131 133 return 0; 132 134 }
+11
security/landlock/domain.h
··· 24 24 enum landlock_log_status { 25 25 LANDLOCK_LOG_PENDING = 0, 26 26 LANDLOCK_LOG_RECORDED, 27 + LANDLOCK_LOG_DISABLED, 27 28 }; 28 29 29 30 /** ··· 104 103 * @details: Information about the related domain. 105 104 */ 106 105 const struct landlock_details *details; 106 + /** 107 + * @log_same_exec: Set if the domain is *not* configured with 108 + * %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF. Set to true by default. 109 + */ 110 + u32 log_same_exec : 1, 111 + /** 112 + * @log_new_exec: Set if the domain is configured with 113 + * %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON. Set to false by default. 114 + */ 115 + log_new_exec : 1; 107 116 #endif /* CONFIG_AUDIT */ 108 117 }; 109 118
+6 -1
security/landlock/limits.h
··· 1 1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 2 /* 3 - * Landlock LSM - Limits for different components 3 + * Landlock - Limits for different components 4 4 * 5 5 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net> 6 6 * Copyright © 2018-2020 ANSSI 7 + * Copyright © 2021-2025 Microsoft Corporation 7 8 */ 8 9 9 10 #ifndef _SECURITY_LANDLOCK_LIMITS_H ··· 30 29 #define LANDLOCK_LAST_SCOPE LANDLOCK_SCOPE_SIGNAL 31 30 #define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1) 32 31 #define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE) 32 + 33 + #define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON 34 + #define LANDLOCK_MASK_RESTRICT_SELF ((LANDLOCK_LAST_RESTRICT_SELF << 1) - 1) 35 + 33 36 /* clang-format on */ 34 37 35 38 #endif /* _SECURITY_LANDLOCK_LIMITS_H */
+31 -8
security/landlock/syscalls.c
··· 1 1 // SPDX-License-Identifier: GPL-2.0-only 2 2 /* 3 - * Landlock LSM - System call implementations and user space interfaces 3 + * Landlock - System call implementations and user space interfaces 4 4 * 5 5 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net> 6 6 * Copyright © 2018-2020 ANSSI 7 + * Copyright © 2021-2025 Microsoft Corporation 7 8 */ 8 9 9 10 #include <asm/current.h> ··· 29 28 #include <uapi/linux/landlock.h> 30 29 31 30 #include "cred.h" 31 + #include "domain.h" 32 32 #include "fs.h" 33 33 #include "limits.h" 34 34 #include "net.h" ··· 153 151 .write = fop_dummy_write, 154 152 }; 155 153 156 - #define LANDLOCK_ABI_VERSION 6 154 + /* 155 + * The Landlock ABI version should be incremented for each new Landlock-related 156 + * user space visible change (e.g. Landlock syscalls). This version should 157 + * only be incremented once per Linux release, and the date in 158 + * Documentation/userspace-api/landlock.rst should be updated to reflect the 159 + * UAPI change. 160 + */ 161 + const int landlock_abi_version = 7; 157 162 158 163 /** 159 164 * sys_landlock_create_ruleset - Create a new ruleset ··· 255 246 landlock_put_ruleset(ruleset); 256 247 return ruleset_fd; 257 248 } 258 - 259 - const int landlock_abi_version = LANDLOCK_ABI_VERSION; 260 249 261 250 /* 262 251 * Returns an owned ruleset from a FD. It is thus needed to call ··· 450 443 * sys_landlock_restrict_self - Enforce a ruleset on the calling thread 451 444 * 452 445 * @ruleset_fd: File descriptor tied to the ruleset to merge with the target. 453 - * @flags: Must be 0. 446 + * @flags: Supported values: 447 + * 448 + * - %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF 449 + * - %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON 454 450 * 455 451 * This system call enables to enforce a Landlock ruleset on the current 456 452 * thread. Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its ··· 463 453 * Possible returned errors are: 464 454 * 465 455 * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; 466 - * - %EINVAL: @flags is not 0. 456 + * - %EINVAL: @flags contains an unknown bit. 467 457 * - %EBADF: @ruleset_fd is not a file descriptor for the current thread; 468 458 * - %EBADFD: @ruleset_fd is not a ruleset file descriptor; 469 459 * - %EPERM: @ruleset_fd has no read access to the underlying ruleset, or the ··· 479 469 *ruleset __free(landlock_put_ruleset) = NULL; 480 470 struct cred *new_cred; 481 471 struct landlock_cred_security *new_llcred; 472 + bool __maybe_unused log_same_exec, log_new_exec; 482 473 483 474 if (!is_initialized()) 484 475 return -EOPNOTSUPP; ··· 492 481 !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) 493 482 return -EPERM; 494 483 495 - /* No flag for now. */ 496 - if (flags) 484 + if ((flags | LANDLOCK_MASK_RESTRICT_SELF) != 485 + LANDLOCK_MASK_RESTRICT_SELF) 497 486 return -EINVAL; 487 + 488 + /* Translates "off" flag to boolean. */ 489 + log_same_exec = !(flags & LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF); 490 + /* Translates "on" flag to boolean. */ 491 + log_new_exec = !!(flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON); 498 492 499 493 /* Gets and checks the ruleset. */ 500 494 ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ); ··· 522 506 abort_creds(new_cred); 523 507 return PTR_ERR(new_dom); 524 508 } 509 + 510 + #ifdef CONFIG_AUDIT 511 + new_dom->hierarchy->log_same_exec = log_same_exec; 512 + new_dom->hierarchy->log_new_exec = log_new_exec; 513 + if (!log_same_exec && !log_new_exec) 514 + new_dom->hierarchy->log_status = LANDLOCK_LOG_DISABLED; 515 + #endif /* CONFIG_AUDIT */ 525 516 526 517 /* Replaces the old (prepared) domain. */ 527 518 landlock_put_ruleset(new_llcred->domain);
+1 -1
tools/testing/selftests/landlock/base_test.c
··· 76 76 const struct landlock_ruleset_attr ruleset_attr = { 77 77 .handled_access_fs = LANDLOCK_ACCESS_FS_READ_FILE, 78 78 }; 79 - ASSERT_EQ(6, landlock_create_ruleset(NULL, 0, 79 + ASSERT_EQ(7, landlock_create_ruleset(NULL, 0, 80 80 LANDLOCK_CREATE_RULESET_VERSION)); 81 81 82 82 ASSERT_EQ(-1, landlock_create_ruleset(&ruleset_attr, 0,