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_SUBDOMAINS_OFF

Add LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF for the case of sandboxer
tools, init systems, or runtime containers launching programs sandboxing
themselves in an inconsistent way. Setting this flag should only
depends on runtime configuration (i.e. not hardcoded).

We don't create a new ruleset's option because this should not be part
of the security policy: only the task that enforces the policy (not the
one that create it) knows if itself or its children may request denied
actions.

This is the first and only flag that can be set without actually
restricting the caller (i.e. without providing a ruleset).

Extend struct landlock_cred_security with a u8 log_subdomains_off.
struct landlock_file_security is still 16 bytes.

Cc: Günther Noack <gnoack@google.com>
Cc: Paul Moore <paul@paul-moore.com>
Closes: https://github.com/landlock-lsm/linux/issues/3
Link: https://lore.kernel.org/r/20250320190717.2287696-19-mic@digikod.net
[mic: Fix comment]
Signed-off-by: Mickaël Salaün <mic@digikod.net>

+55 -7
+12
include/uapi/linux/landlock.h
··· 79 79 * This flag should only be set if all the programs than can legitimately be 80 80 * executed will not try to request a denied access (which could spam audit 81 81 * logs). 82 + * - %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF: Do not create any log related 83 + * to the enforced restrictions coming from future nested domains created by 84 + * the caller or its descendants. This should only be set according to a 85 + * runtime configuration (i.e. not hardcoded) by programs launching other 86 + * unknown or untrusted programs that may create their own Landlock domains 87 + * and spam logs. The main use case is for container runtimes to enable users 88 + * to mute buggy sandboxed programs for a specific container image. Other use 89 + * cases include sandboxer tools and init systems. Unlike 90 + * %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF, 91 + * %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF does not impact the requested 92 + * restriction (if any) but only the future nested domains. 82 93 */ 83 94 /* clang-format off */ 84 95 #define LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF (1U << 0) 85 96 #define LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON (1U << 1) 97 + #define LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF (1U << 2) 86 98 /* clang-format on */ 87 99 88 100 /**
+7
security/landlock/cred.h
··· 40 40 * landlock_restrict_self(2)). 41 41 */ 42 42 u16 domain_exec; 43 + /** 44 + * @log_subdomains_off: Set if the domain descendants's log_status should be 45 + * set to %LANDLOCK_LOG_DISABLED. This is not a landlock_hierarchy 46 + * configuration because it applies to future descendant domains and it does 47 + * not require a current domain. 48 + */ 49 + u8 log_subdomains_off : 1; 43 50 #endif /* CONFIG_AUDIT */ 44 51 } __packed; 45 52
+1 -1
security/landlock/limits.h
··· 31 31 #define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1) 32 32 #define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE) 33 33 34 - #define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON 34 + #define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF 35 35 #define LANDLOCK_MASK_RESTRICT_SELF ((LANDLOCK_LAST_RESTRICT_SELF << 1) - 1) 36 36 37 37 /* clang-format on */
+35 -6
security/landlock/syscalls.c
··· 454 454 * 455 455 * - %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF 456 456 * - %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON 457 + * - %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF 457 458 * 458 459 * This system call enables to enforce a Landlock ruleset on the current 459 460 * thread. Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its 460 461 * namespace or is running with no_new_privs. This avoids scenarios where 461 462 * unprivileged tasks can affect the behavior of privileged children. 463 + * 464 + * It is allowed to only pass the %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF 465 + * flag with a @ruleset_fd value of -1. 462 466 * 463 467 * Possible returned errors are: 464 468 * ··· 483 479 *ruleset __free(landlock_put_ruleset) = NULL; 484 480 struct cred *new_cred; 485 481 struct landlock_cred_security *new_llcred; 486 - bool __maybe_unused log_same_exec, log_new_exec; 482 + bool __maybe_unused log_same_exec, log_new_exec, log_subdomains, 483 + prev_log_subdomains; 487 484 488 485 if (!is_initialized()) 489 486 return -EOPNOTSUPP; ··· 505 500 log_same_exec = !(flags & LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF); 506 501 /* Translates "on" flag to boolean. */ 507 502 log_new_exec = !!(flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON); 503 + /* Translates "off" flag to boolean. */ 504 + log_subdomains = !(flags & LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF); 508 505 509 - /* Gets and checks the ruleset. */ 510 - ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ); 511 - if (IS_ERR(ruleset)) 512 - return PTR_ERR(ruleset); 506 + /* 507 + * It is allowed to set LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF with 508 + * -1 as ruleset_fd, but no other flag must be set. 509 + */ 510 + if (!(ruleset_fd == -1 && 511 + flags == LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) { 512 + /* Gets and checks the ruleset. */ 513 + ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ); 514 + if (IS_ERR(ruleset)) 515 + return PTR_ERR(ruleset); 516 + } 513 517 514 518 /* Prepares new credentials. */ 515 519 new_cred = prepare_creds(); ··· 526 512 return -ENOMEM; 527 513 528 514 new_llcred = landlock_cred(new_cred); 515 + 516 + #ifdef CONFIG_AUDIT 517 + prev_log_subdomains = !new_llcred->log_subdomains_off; 518 + new_llcred->log_subdomains_off = !prev_log_subdomains || 519 + !log_subdomains; 520 + #endif /* CONFIG_AUDIT */ 521 + 522 + /* 523 + * The only case when a ruleset may not be set is if 524 + * LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF is set and ruleset_fd is -1. 525 + * We could optimize this case by not calling commit_creds() if this flag 526 + * was already set, but it is not worth the complexity. 527 + */ 528 + if (!ruleset) 529 + return commit_creds(new_cred); 529 530 530 531 /* 531 532 * There is no possible race condition while copying and manipulating ··· 555 526 #ifdef CONFIG_AUDIT 556 527 new_dom->hierarchy->log_same_exec = log_same_exec; 557 528 new_dom->hierarchy->log_new_exec = log_new_exec; 558 - if (!log_same_exec && !log_new_exec) 529 + if ((!log_same_exec && !log_new_exec) || !prev_log_subdomains) 559 530 new_dom->hierarchy->log_status = LANDLOCK_LOG_DISABLED; 560 531 #endif /* CONFIG_AUDIT */ 561 532