Message ID | 20250131163059.1139617-18-mic@digikod.net (mailing list archive) |
---|---|
State | New |
Headers | show |
Series | Landlock audit support | expand |
Hi Mickaël, kernel test robot noticed the following build warnings: [auto build test WARNING on 69e858e0b8b2ea07759e995aa383e8780d9d140c] url: https://github.com/intel-lab-lkp/linux/commits/Micka-l-Sala-n/lsm-Add-audit_log_lsm_data-helper/20250201-004434 base: 69e858e0b8b2ea07759e995aa383e8780d9d140c patch link: https://lore.kernel.org/r/20250131163059.1139617-18-mic%40digikod.net patch subject: [PATCH v5 17/24] landlock: Add LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS config: x86_64-buildonly-randconfig-002-20250201 (https://download.01.org/0day-ci/archive/20250201/202502010411.lOcXpnOG-lkp@intel.com/config) compiler: gcc-12 (Debian 12.2.0-14) 12.2.0 reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20250201/202502010411.lOcXpnOG-lkp@intel.com/reproduce) If you fix the issue in a separate patch/commit (i.e. not just a new version of the same patch/commit), kindly add following tags | Reported-by: kernel test robot <lkp@intel.com> | Closes: https://lore.kernel.org/oe-kbuild-all/202502010411.lOcXpnOG-lkp@intel.com/ All warnings (new ones prefixed by >>): security/landlock/syscalls.c: In function '__do_sys_landlock_restrict_self': >> security/landlock/syscalls.c:469:24: warning: variable 'is_quiet_subdomains' set but not used [-Wunused-but-set-variable] 469 | bool is_quiet, is_quiet_subdomains, | ^~~~~~~~~~~~~~~~~~~ security/landlock/syscalls.c:469:14: warning: variable 'is_quiet' set but not used [-Wunused-but-set-variable] 469 | bool is_quiet, is_quiet_subdomains, | ^~~~~~~~ vim +/is_quiet_subdomains +469 security/landlock/syscalls.c 435 436 /** 437 * sys_landlock_restrict_self - Enforce a ruleset on the calling thread 438 * 439 * @ruleset_fd: File descriptor tied to the ruleset to merge with the target. 440 * @flags: Supported values: 441 * 442 * - %LANDLOCK_RESTRICT_SELF_QUIET 443 * - %LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS 444 * 445 * This system call enables to enforce a Landlock ruleset on the current 446 * thread. Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its 447 * namespace or is running with no_new_privs. This avoids scenarios where 448 * unprivileged tasks can affect the behavior of privileged children. 449 * 450 * Possible returned errors are: 451 * 452 * - %EOPNOTSUPP: Landlock is supported by the kernel but disabled at boot time; 453 * - %EINVAL: @flags contains an unknown bit. 454 * - %EBADF: @ruleset_fd is not a file descriptor for the current thread; 455 * - %EBADFD: @ruleset_fd is not a ruleset file descriptor; 456 * - %EPERM: @ruleset_fd has no read access to the underlying ruleset, or the 457 * current thread is not running with no_new_privs, or it doesn't have 458 * %CAP_SYS_ADMIN in its namespace. 459 * - %E2BIG: The maximum number of stacked rulesets is reached for the current 460 * thread. 461 */ 462 SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, 463 flags) 464 { 465 struct landlock_ruleset *new_dom, 466 *ruleset __free(landlock_put_ruleset) = NULL; 467 struct cred *new_cred; 468 struct landlock_cred_security *new_llcred; > 469 bool is_quiet, is_quiet_subdomains, 470 __maybe_unused inherits_quiet_subdomains; 471 472 if (!is_initialized()) 473 return -EOPNOTSUPP; 474 475 /* 476 * Similar checks as for seccomp(2), except that an -EPERM may be 477 * returned. 478 */ 479 if (!task_no_new_privs(current) && 480 !ns_capable_noaudit(current_user_ns(), CAP_SYS_ADMIN)) 481 return -EPERM; 482 483 if ((flags | LANDLOCK_MASK_RESTRICT_SELF) != 484 LANDLOCK_MASK_RESTRICT_SELF) 485 return -EINVAL; 486 487 is_quiet = !!(flags & LANDLOCK_RESTRICT_SELF_QUIET); 488 is_quiet_subdomains = 489 !!(flags & LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS); 490 491 /* Gets and checks the ruleset. */ 492 ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ); 493 if (IS_ERR(ruleset)) 494 return PTR_ERR(ruleset); 495 496 /* Prepares new credentials. */ 497 new_cred = prepare_creds(); 498 if (!new_cred) 499 return -ENOMEM; 500 501 new_llcred = landlock_cred(new_cred); 502 503 /* 504 * There is no possible race condition while copying and manipulating 505 * the current credentials because they are dedicated per thread. 506 */ 507 new_dom = landlock_merge_ruleset(new_llcred->domain, ruleset); 508 if (IS_ERR(new_dom)) { 509 abort_creds(new_cred); 510 return PTR_ERR(new_dom); 511 } 512
diff --git a/include/uapi/linux/landlock.h b/include/uapi/linux/landlock.h index b7f78abd6ddd..d810fd9e17c6 100644 --- a/include/uapi/linux/landlock.h +++ b/include/uapi/linux/landlock.h @@ -71,9 +71,20 @@ struct landlock_ruleset_attr { * service manager). Because programs sandboxing themselves should fix any * denied access, they should not set this flag to be aware of potential * issues reported by system's logs (i.e. audit). + * - %LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS: Do not create any log related + * to the enforced restrictions coming from descendant domains. This should + * only be set according to a runtime configuration (i.e. not hardcoded) by + * programs launching other unknown or untrusted programs that may create + * their own Landlock domains and spam logs. The main use case is for + * container runtimes to enable users to mute buggy sandboxed programs for a + * specific container image. Other use cases include sandboxer tools and + * init systems. Unlike %LANDLOCK_RESTRICT_SELF_QUIET, + * %LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS does not impact the requested + * restriction but only the potential descendant domains. */ /* clang-format off */ #define LANDLOCK_RESTRICT_SELF_QUIET (1U << 0) +#define LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS (1U << 1) /* clang-format on */ /** diff --git a/security/landlock/domain.c b/security/landlock/domain.c index 6704e9283206..eff7c774bf06 100644 --- a/security/landlock/domain.c +++ b/security/landlock/domain.c @@ -127,6 +127,7 @@ int landlock_init_hierarchy_log(struct landlock_hierarchy *const hierarchy) hierarchy->details = details; hierarchy->id = landlock_get_id_range(1); hierarchy->log_status = LANDLOCK_LOG_PENDING; + hierarchy->quiet_subdomains = false; atomic64_set(&hierarchy->num_denials, 0); return 0; } diff --git a/security/landlock/domain.h b/security/landlock/domain.h index 25be0a18da1f..8979cf00f8be 100644 --- a/security/landlock/domain.h +++ b/security/landlock/domain.h @@ -104,6 +104,11 @@ struct landlock_hierarchy { * @details: Information about the related domain. */ const struct landlock_details *details; + /** + * @quiet_subdomains: Set if the domain descendants's log_status + * should be set to %LANDLOCK_LOG_DISABLED. + */ + u32 quiet_subdomains : 1; #endif /* CONFIG_AUDIT */ }; diff --git a/security/landlock/limits.h b/security/landlock/limits.h index 2a5e9f3ee750..48aa75c98665 100644 --- a/security/landlock/limits.h +++ b/security/landlock/limits.h @@ -30,7 +30,7 @@ #define LANDLOCK_MASK_SCOPE ((LANDLOCK_LAST_SCOPE << 1) - 1) #define LANDLOCK_NUM_SCOPE __const_hweight64(LANDLOCK_MASK_SCOPE) -#define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_QUIET +#define LANDLOCK_LAST_RESTRICT_SELF LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS #define LANDLOCK_MASK_RESTRICT_SELF ((LANDLOCK_LAST_RESTRICT_SELF << 1) - 1) /* clang-format on */ diff --git a/security/landlock/syscalls.c b/security/landlock/syscalls.c index 5c6abcd6d604..f44f4f884499 100644 --- a/security/landlock/syscalls.c +++ b/security/landlock/syscalls.c @@ -440,6 +440,7 @@ SYSCALL_DEFINE4(landlock_add_rule, const int, ruleset_fd, * @flags: Supported values: * * - %LANDLOCK_RESTRICT_SELF_QUIET + * - %LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS * * This system call enables to enforce a Landlock ruleset on the current * thread. Enforcing a ruleset requires that the task has %CAP_SYS_ADMIN in its @@ -465,7 +466,8 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, *ruleset __free(landlock_put_ruleset) = NULL; struct cred *new_cred; struct landlock_cred_security *new_llcred; - bool is_quiet; + bool is_quiet, is_quiet_subdomains, + __maybe_unused inherits_quiet_subdomains; if (!is_initialized()) return -EOPNOTSUPP; @@ -483,6 +485,8 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, return -EINVAL; is_quiet = !!(flags & LANDLOCK_RESTRICT_SELF_QUIET); + is_quiet_subdomains = + !!(flags & LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS); /* Gets and checks the ruleset. */ ruleset = get_ruleset_from_fd(ruleset_fd, FMODE_CAN_READ); @@ -506,11 +510,15 @@ SYSCALL_DEFINE2(landlock_restrict_self, const int, ruleset_fd, const __u32, return PTR_ERR(new_dom); } - if (is_quiet) { #ifdef CONFIG_AUDIT + inherits_quiet_subdomains = + new_llcred->domain && + new_llcred->domain->hierarchy->quiet_subdomains; + new_dom->hierarchy->quiet_subdomains = is_quiet_subdomains || + inherits_quiet_subdomains; + if (is_quiet || inherits_quiet_subdomains) new_dom->hierarchy->log_status = LANDLOCK_LOG_DISABLED; #endif /* CONFIG_AUDIT */ - } /* Replaces the old (prepared) domain. */ landlock_put_ruleset(new_llcred->domain);
Add LANDLOCK_RESTRICT_SELF_QUIET_SUBDOMAINS 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. Cc: Günther Noack <gnoack@google.com> Cc: Paul Moore <paul@paul-moore.com> Signed-off-by: Mickaël Salaün <mic@digikod.net> Link: https://lore.kernel.org/r/20250131163059.1139617-18-mic@digikod.net --- Using "mute" instead of "quiet" might be more appropriate. Changes since v4: - New patch. --- include/uapi/linux/landlock.h | 11 +++++++++++ security/landlock/domain.c | 1 + security/landlock/domain.h | 5 +++++ security/landlock/limits.h | 2 +- security/landlock/syscalls.c | 14 +++++++++++--- 5 files changed, 29 insertions(+), 4 deletions(-)