Skip to content

Commit ead9079

Browse files
committed
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 <[email protected]> Cc: Paul Moore <[email protected]> Closes: landlock-lsm/linux#3 Link: https://lore.kernel.org/r/[email protected] [mic: Fix comment] Signed-off-by: Mickaël Salaün <[email protected]>
1 parent 12bfcda commit ead9079

File tree

4 files changed

+55
-7
lines changed

4 files changed

+55
-7
lines changed

include/uapi/linux/landlock.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,10 +79,22 @@ struct landlock_ruleset_attr {
7979
* This flag should only be set if all the programs than can legitimately be
8080
* executed will not try to request a denied access (which could spam audit
8181
* 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.
8293
*/
8394
/* clang-format off */
8495
#define LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF (1U << 0)
8596
#define LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON (1U << 1)
97+
#define LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF (1U << 2)
8698
/* clang-format on */
8799

88100
/**

security/landlock/cred.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,13 @@ struct landlock_cred_security {
4040
* landlock_restrict_self(2)).
4141
*/
4242
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;
4350
#endif /* CONFIG_AUDIT */
4451
} __packed;
4552

security/landlock/limits.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
#define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1)
3232
#define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE)
3333

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
3535
#define LANDLOCK_MASK_RESTRICT_SELF ((LANDLOCK_LAST_RESTRICT_SELF << 1) - 1)
3636

3737
/* clang-format on */

security/landlock/syscalls.c

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -454,12 +454,16 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd,
454454
*
455455
* - %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF
456456
* - %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON
457+
* - %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF
457458
*
458459
* This system call enables to enforce a Landlock ruleset on the current
459460
* thread. Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its
460461
* namespace or is running with no_new_privs. This avoids scenarios where
461462
* unprivileged tasks can affect the behavior of privileged children.
462463
*
464+
* It is allowed to only pass the %LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF
465+
* flag with a @ruleset_fd value of -1.
466+
*
463467
* Possible returned errors are:
464468
*
465469
* - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time;
@@ -479,7 +483,8 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
479483
*ruleset __free(landlock_put_ruleset) = NULL;
480484
struct cred *new_cred;
481485
struct landlock_cred_security *new_llcred;
482-
bool __maybe_unused log_same_exec, log_new_exec;
486+
bool __maybe_unused log_same_exec, log_new_exec, log_subdomains,
487+
prev_log_subdomains;
483488

484489
if (!is_initialized())
485490
return -EOPNOTSUPP;
@@ -500,11 +505,20 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
500505
log_same_exec = !(flags & LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF);
501506
/* Translates "on" flag to boolean. */
502507
log_new_exec = !!(flags & LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON);
508+
/* Translates "off" flag to boolean. */
509+
log_subdomains = !(flags & LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF);
503510

504-
/* Gets and checks the ruleset. */
505-
ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ);
506-
if (IS_ERR(ruleset))
507-
return PTR_ERR(ruleset);
511+
/*
512+
* It is allowed to set LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF with
513+
* -1 as ruleset_fd, but no other flag must be set.
514+
*/
515+
if (!(ruleset_fd == -1 &&
516+
flags == LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF)) {
517+
/* Gets and checks the ruleset. */
518+
ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ);
519+
if (IS_ERR(ruleset))
520+
return PTR_ERR(ruleset);
521+
}
508522

509523
/* Prepares new credentials. */
510524
new_cred = prepare_creds();
@@ -513,6 +527,21 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
513527

514528
new_llcred = landlock_cred(new_cred);
515529

530+
#ifdef CONFIG_AUDIT
531+
prev_log_subdomains = !new_llcred->log_subdomains_off;
532+
new_llcred->log_subdomains_off = !prev_log_subdomains ||
533+
!log_subdomains;
534+
#endif /* CONFIG_AUDIT */
535+
536+
/*
537+
* The only case when a ruleset may not be set is if
538+
* LANDLOCK_RESTRICT_SELF_LOG_SUBDOMAINS_OFF is set and ruleset_fd is -1.
539+
* We could optimize this case by not calling commit_creds() if this flag
540+
* was already set, but it is not worth the complexity.
541+
*/
542+
if (!ruleset)
543+
return commit_creds(new_cred);
544+
516545
/*
517546
* There is no possible race condition while copying and manipulating
518547
* the current credentials because they are dedicated per thread.
@@ -526,7 +555,7 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32,
526555
#ifdef CONFIG_AUDIT
527556
new_dom->hierarchy->log_same_exec = log_same_exec;
528557
new_dom->hierarchy->log_new_exec = log_new_exec;
529-
if (!log_same_exec && !log_new_exec)
558+
if ((!log_same_exec && !log_new_exec) || !prev_log_subdomains)
530559
new_dom->hierarchy->log_status = LANDLOCK_LOG_DISABLED;
531560
#endif /* CONFIG_AUDIT */
532561

0 commit comments

Comments
 (0)