Unverified Commit 12bfcda7 authored by Mickaël Salaün's avatar Mickaël Salaün
Browse files

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: default avatarMickaël Salaün <mic@digikod.net>
parent 1176a15b
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
@@ -4,6 +4,7 @@
 *
 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2018-2020 ANSSI
 * Copyright © 2021-2025 Microsoft Corporation
 */

#ifndef _UAPI_LINUX_LANDLOCK_H
@@ -64,6 +65,26 @@ struct landlock_ruleset_attr {
#define LANDLOCK_CREATE_RULESET_ERRATA			(1U << 1)
/* clang-format on */

/*
 * sys_landlock_restrict_self() flags:
 *
 * - %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF: Do not create any log related to the
 *   enforced restrictions.  This should only be set by tools launching unknown
 *   or untrusted programs (e.g. a sandbox tool, container runtime, system
 *   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_LOG_NEW_EXEC_ON: Explicitly ask to continue
 *   logging denied access requests even after an :manpage:`execve(2)` call.
 *   This flag should only be set if all the programs than can legitimately be
 *   executed will not try to request a denied access (which could spam audit
 *   logs).
 */
/* clang-format off */
#define LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF		(1U << 0)
#define LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON			(1U << 1)
/* clang-format on */

/**
 * enum landlock_rule_type - Landlock rule type
 *
+13 −3
Original line number Diff line number Diff line
@@ -422,6 +422,9 @@ void landlock_log_denial(const struct landlock_cred_security *const subject,
			get_hierarchy(subject->domain, youngest_layer);
	}

	if (READ_ONCE(youngest_denied->log_status) == LANDLOCK_LOG_DISABLED)
		return;

	/*
	 * Consistently keeps track of the number of denied access requests
	 * even if audit is currently disabled, or if audit rules currently
@@ -433,9 +436,16 @@ void landlock_log_denial(const struct landlock_cred_security *const subject,
	if (!audit_enabled)
		return;

	/* Ignores denials after an execution. */
	if (!(subject->domain_exec & (1 << youngest_layer)))
	/* Checks if the current exec was restricting itself. */
	if (subject->domain_exec & (1 << youngest_layer)) {
		/* Ignores denials for the same execution. */
		if (!youngest_denied->log_same_exec)
			return;
	} else {
		/* Ignores denials after a new execution. */
		if (!youngest_denied->log_new_exec)
			return;
	}

	/* Uses consistent allocation flags wrt common_lsm_audit(). */
	ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
+2 −0
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@ 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->log_same_exec = true;
	hierarchy->log_new_exec = false;
	atomic64_set(&hierarchy->num_denials, 0);
	return 0;
}
+11 −0
Original line number Diff line number Diff line
@@ -24,6 +24,7 @@
enum landlock_log_status {
	LANDLOCK_LOG_PENDING = 0,
	LANDLOCK_LOG_RECORDED,
	LANDLOCK_LOG_DISABLED,
};

/**
@@ -103,6 +104,16 @@ struct landlock_hierarchy {
	 * @details: Information about the related domain.
	 */
	const struct landlock_details *details;
	/**
	 * @log_same_exec: Set if the domain is *not* configured with
	 * %LANDLOCK_RESTRICT_SELF_LOG_SAME_EXEC_OFF.  Set to true by default.
	 */
	u32 log_same_exec : 1,
		/**
		 * @log_new_exec: Set if the domain is configured with
		 * %LANDLOCK_RESTRICT_SELF_LOG_NEW_EXEC_ON.  Set to false by default.
		 */
		log_new_exec : 1;
#endif /* CONFIG_AUDIT */
};

+6 −1
Original line number Diff line number Diff line
/* SPDX-License-Identifier: GPL-2.0-only */
/*
 * Landlock LSM - Limits for different components
 * Landlock - Limits for different components
 *
 * Copyright © 2016-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2018-2020 ANSSI
 * Copyright © 2021-2025 Microsoft Corporation
 */

#ifndef _SECURITY_LANDLOCK_LIMITS_H
@@ -29,6 +30,10 @@
#define LANDLOCK_LAST_SCOPE		LANDLOCK_SCOPE_SIGNAL
#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_LOG_NEW_EXEC_ON
#define LANDLOCK_MASK_RESTRICT_SELF	((LANDLOCK_LAST_RESTRICT_SELF << 1) - 1)

/* clang-format on */

#endif /* _SECURITY_LANDLOCK_LIMITS_H */
Loading