// SPDX-License-Identifier: GPL-2.0-only
/*
 * Landlock - Audit helpers
 *
 * Copyright © 2023-2025 Microsoft Corporation
 */

#include <kunit/test.h>
#include <linux/audit.h>
#include <linux/bitops.h>
#include <linux/lsm_audit.h>
#include <linux/pid.h>
#include <uapi/linux/landlock.h>

#include "access.h"
#include "audit.h"
#include "common.h"
#include "cred.h"
#include "domain.h"
#include "limits.h"
#include "ruleset.h"

static const char *const fs_access_strings[] = {
	[BIT_INDEX(LANDLOCK_ACCESS_FS_EXECUTE)] = "fs.execute",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_WRITE_FILE)] = "fs.write_file",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_READ_FILE)] = "fs.read_file",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_READ_DIR)] = "fs.read_dir",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_REMOVE_DIR)] = "fs.remove_dir",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_REMOVE_FILE)] = "fs.remove_file",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_CHAR)] = "fs.make_char",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_DIR)] = "fs.make_dir",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_REG)] = "fs.make_reg",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_SOCK)] = "fs.make_sock",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_FIFO)] = "fs.make_fifo",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_BLOCK)] = "fs.make_block",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_MAKE_SYM)] = "fs.make_sym",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_REFER)] = "fs.refer",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_TRUNCATE)] = "fs.truncate",
	[BIT_INDEX(LANDLOCK_ACCESS_FS_IOCTL_DEV)] = "fs.ioctl_dev",
};

static_assert(ARRAY_SIZE(fs_access_strings) == LANDLOCK_NUM_ACCESS_FS);

static const char *const net_access_strings[] = {
	[BIT_INDEX(LANDLOCK_ACCESS_NET_BIND_TCP)] = "net.bind_tcp",
	[BIT_INDEX(LANDLOCK_ACCESS_NET_CONNECT_TCP)] = "net.connect_tcp",
};

static_assert(ARRAY_SIZE(net_access_strings) == LANDLOCK_NUM_ACCESS_NET);

static __attribute_const__ const char *
get_blocker(const enum landlock_request_type type,
	    const unsigned long access_bit)
{
	switch (type) {
	case LANDLOCK_REQUEST_PTRACE:
		WARN_ON_ONCE(access_bit != -1);
		return "ptrace";

	case LANDLOCK_REQUEST_FS_CHANGE_TOPOLOGY:
		WARN_ON_ONCE(access_bit != -1);
		return "fs.change_topology";

	case LANDLOCK_REQUEST_FS_ACCESS:
		if (WARN_ON_ONCE(access_bit >= ARRAY_SIZE(fs_access_strings)))
			return "unknown";
		return fs_access_strings[access_bit];

	case LANDLOCK_REQUEST_NET_ACCESS:
		if (WARN_ON_ONCE(access_bit >= ARRAY_SIZE(net_access_strings)))
			return "unknown";
		return net_access_strings[access_bit];

	case LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET:
		WARN_ON_ONCE(access_bit != -1);
		return "scope.abstract_unix_socket";

	case LANDLOCK_REQUEST_SCOPE_SIGNAL:
		WARN_ON_ONCE(access_bit != -1);
		return "scope.signal";
	}

	WARN_ON_ONCE(1);
	return "unknown";
}

static void log_blockers(struct audit_buffer *const ab,
			 const enum landlock_request_type type,
			 const access_mask_t access)
{
	const unsigned long access_mask = access;
	unsigned long access_bit;
	bool is_first = true;

	for_each_set_bit(access_bit, &access_mask, BITS_PER_TYPE(access)) {
		audit_log_format(ab, "%s%s", is_first ? "" : ",",
				 get_blocker(type, access_bit));
		is_first = false;
	}
	if (is_first)
		audit_log_format(ab, "%s", get_blocker(type, -1));
}

static void log_domain(struct landlock_hierarchy *const hierarchy)
{
	struct audit_buffer *ab;

	/* Ignores already logged domains.  */
	if (READ_ONCE(hierarchy->log_status) == LANDLOCK_LOG_RECORDED)
		return;

	/* Uses consistent allocation flags wrt common_lsm_audit(). */
	ab = audit_log_start(audit_context(), GFP_ATOMIC | __GFP_NOWARN,
			     AUDIT_LANDLOCK_DOMAIN);
	if (!ab)
		return;

	WARN_ON_ONCE(hierarchy->id == 0);
	audit_log_format(
		ab,
		"domain=%llx status=allocated mode=enforcing pid=%d uid=%u exe=",
		hierarchy->id, pid_nr(hierarchy->details->pid),
		hierarchy->details->uid);
	audit_log_untrustedstring(ab, hierarchy->details->exe_path);
	audit_log_format(ab, " comm=");
	audit_log_untrustedstring(ab, hierarchy->details->comm);
	audit_log_end(ab);

	/*
	 * There may be race condition leading to logging of the same domain
	 * several times but that is OK.
	 */
	WRITE_ONCE(hierarchy->log_status, LANDLOCK_LOG_RECORDED);
}

static struct landlock_hierarchy *
get_hierarchy(const struct landlock_ruleset *const domain, const size_t layer)
{
	struct landlock_hierarchy *hierarchy = domain->hierarchy;
	ssize_t i;

	if (WARN_ON_ONCE(layer >= domain->num_layers))
		return hierarchy;

	for (i = domain->num_layers - 1; i > layer; i--) {
		if (WARN_ON_ONCE(!hierarchy->parent))
			break;

		hierarchy = hierarchy->parent;
	}

	return hierarchy;
}

#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST

static void test_get_hierarchy(struct kunit *const test)
{
	struct landlock_hierarchy dom0_hierarchy = {
		.id = 10,
	};
	struct landlock_hierarchy dom1_hierarchy = {
		.parent = &dom0_hierarchy,
		.id = 20,
	};
	struct landlock_hierarchy dom2_hierarchy = {
		.parent = &dom1_hierarchy,
		.id = 30,
	};
	struct landlock_ruleset dom2 = {
		.hierarchy = &dom2_hierarchy,
		.num_layers = 3,
	};

	KUNIT_EXPECT_EQ(test, 10, get_hierarchy(&dom2, 0)->id);
	KUNIT_EXPECT_EQ(test, 20, get_hierarchy(&dom2, 1)->id);
	KUNIT_EXPECT_EQ(test, 30, get_hierarchy(&dom2, 2)->id);
	/* KUNIT_EXPECT_EQ(test, 30, get_hierarchy(&dom2, -1)->id); */
}

#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */

/* Get the youngest layer that denied the access_request. */
static size_t get_denied_layer(const struct landlock_ruleset *const domain,
			       access_mask_t *const access_request,
			       const struct layer_access_masks *masks)
{
	for (ssize_t i = ARRAY_SIZE(masks->access) - 1; i >= 0; i--) {
		if (masks->access[i] & *access_request) {
			*access_request &= masks->access[i];
			return i;
		}
	}

	/* Not found - fall back to default values */
	*access_request = 0;
	return domain->num_layers - 1;
}

#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST

static void test_get_denied_layer(struct kunit *const test)
{
	const struct landlock_ruleset dom = {
		.num_layers = 5,
	};
	const struct layer_access_masks masks = {
		.access[0] = LANDLOCK_ACCESS_FS_EXECUTE |
			     LANDLOCK_ACCESS_FS_READ_DIR,
		.access[1] = LANDLOCK_ACCESS_FS_READ_FILE |
			     LANDLOCK_ACCESS_FS_READ_DIR,
		.access[2] = LANDLOCK_ACCESS_FS_REMOVE_DIR,
	};
	access_mask_t access;

	access = LANDLOCK_ACCESS_FS_EXECUTE;
	KUNIT_EXPECT_EQ(test, 0, get_denied_layer(&dom, &access, &masks));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_EXECUTE);

	access = LANDLOCK_ACCESS_FS_READ_FILE;
	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_FILE);

	access = LANDLOCK_ACCESS_FS_READ_DIR;
	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_DIR);

	access = LANDLOCK_ACCESS_FS_READ_FILE | LANDLOCK_ACCESS_FS_READ_DIR;
	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
	KUNIT_EXPECT_EQ(test, access,
			LANDLOCK_ACCESS_FS_READ_FILE |
				LANDLOCK_ACCESS_FS_READ_DIR);

	access = LANDLOCK_ACCESS_FS_EXECUTE | LANDLOCK_ACCESS_FS_READ_DIR;
	KUNIT_EXPECT_EQ(test, 1, get_denied_layer(&dom, &access, &masks));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_READ_DIR);

	access = LANDLOCK_ACCESS_FS_WRITE_FILE;
	KUNIT_EXPECT_EQ(test, 4, get_denied_layer(&dom, &access, &masks));
	KUNIT_EXPECT_EQ(test, access, 0);
}

#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */

static size_t
get_layer_from_deny_masks(access_mask_t *const access_request,
			  const access_mask_t all_existing_optional_access,
			  const deny_masks_t deny_masks)
{
	const unsigned long access_opt = all_existing_optional_access;
	const unsigned long access_req = *access_request;
	access_mask_t missing = 0;
	size_t youngest_layer = 0;
	size_t access_index = 0;
	unsigned long access_bit;

	/* This will require change with new object types. */
	WARN_ON_ONCE(access_opt != _LANDLOCK_ACCESS_FS_OPTIONAL);

	for_each_set_bit(access_bit, &access_opt,
			 BITS_PER_TYPE(access_mask_t)) {
		if (access_req & BIT(access_bit)) {
			const size_t layer =
				(deny_masks >> (access_index * 4)) &
				(LANDLOCK_MAX_NUM_LAYERS - 1);

			if (layer > youngest_layer) {
				youngest_layer = layer;
				missing = BIT(access_bit);
			} else if (layer == youngest_layer) {
				missing |= BIT(access_bit);
			}
		}
		access_index++;
	}

	*access_request = missing;
	return youngest_layer;
}

#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST

static void test_get_layer_from_deny_masks(struct kunit *const test)
{
	deny_masks_t deny_mask;
	access_mask_t access;

	/* truncate:0 ioctl_dev:2 */
	deny_mask = 0x20;

	access = LANDLOCK_ACCESS_FS_TRUNCATE;
	KUNIT_EXPECT_EQ(test, 0,
			get_layer_from_deny_masks(&access,
						  _LANDLOCK_ACCESS_FS_OPTIONAL,
						  deny_mask));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_TRUNCATE);

	access = LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_IOCTL_DEV;
	KUNIT_EXPECT_EQ(test, 2,
			get_layer_from_deny_masks(&access,
						  _LANDLOCK_ACCESS_FS_OPTIONAL,
						  deny_mask));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_IOCTL_DEV);

	/* truncate:15 ioctl_dev:15 */
	deny_mask = 0xff;

	access = LANDLOCK_ACCESS_FS_TRUNCATE;
	KUNIT_EXPECT_EQ(test, 15,
			get_layer_from_deny_masks(&access,
						  _LANDLOCK_ACCESS_FS_OPTIONAL,
						  deny_mask));
	KUNIT_EXPECT_EQ(test, access, LANDLOCK_ACCESS_FS_TRUNCATE);

	access = LANDLOCK_ACCESS_FS_TRUNCATE | LANDLOCK_ACCESS_FS_IOCTL_DEV;
	KUNIT_EXPECT_EQ(test, 15,
			get_layer_from_deny_masks(&access,
						  _LANDLOCK_ACCESS_FS_OPTIONAL,
						  deny_mask));
	KUNIT_EXPECT_EQ(test, access,
			LANDLOCK_ACCESS_FS_TRUNCATE |
				LANDLOCK_ACCESS_FS_IOCTL_DEV);
}

#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */

static bool is_valid_request(const struct landlock_request *const request)
{
	if (WARN_ON_ONCE(request->layer_plus_one > LANDLOCK_MAX_NUM_LAYERS))
		return false;

	if (WARN_ON_ONCE(!(!!request->layer_plus_one ^ !!request->access)))
		return false;

	if (request->access) {
		if (WARN_ON_ONCE(!(!!request->layer_masks ^
				   !!request->all_existing_optional_access)))
			return false;
	} else {
		if (WARN_ON_ONCE(request->layer_masks ||
				 request->all_existing_optional_access))
			return false;
	}

	if (request->deny_masks) {
		if (WARN_ON_ONCE(!request->all_existing_optional_access))
			return false;
	}

	return true;
}

/**
 * landlock_log_denial - Create audit records related to a denial
 *
 * @subject: The Landlock subject's credential denying an action.
 * @request: Detail of the user space request.
 */
void landlock_log_denial(const struct landlock_cred_security *const subject,
			 const struct landlock_request *const request)
{
	struct audit_buffer *ab;
	struct landlock_hierarchy *youngest_denied;
	size_t youngest_layer;
	access_mask_t missing;

	if (WARN_ON_ONCE(!subject || !subject->domain ||
			 !subject->domain->hierarchy || !request))
		return;

	if (!is_valid_request(request))
		return;

	missing = request->access;
	if (missing) {
		/* Gets the nearest domain that denies the request. */
		if (request->layer_masks) {
			youngest_layer = get_denied_layer(subject->domain,
							  &missing,
							  request->layer_masks);
		} else {
			youngest_layer = get_layer_from_deny_masks(
				&missing, _LANDLOCK_ACCESS_FS_OPTIONAL,
				request->deny_masks);
		}
		youngest_denied =
			get_hierarchy(subject->domain, youngest_layer);
	} else {
		youngest_layer = request->layer_plus_one - 1;
		youngest_denied =
			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
	 * exclude this record type, or if landlock_restrict_self(2)'s flags
	 * quiet logs.
	 */
	atomic64_inc(&youngest_denied->num_denials);

	if (!audit_enabled)
		return;

	/* Checks if the current exec was restricting itself. */
	if (subject->domain_exec & BIT(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,
			     AUDIT_LANDLOCK_ACCESS);
	if (!ab)
		return;

	audit_log_format(ab, "domain=%llx blockers=", youngest_denied->id);
	log_blockers(ab, request->type, missing);
	audit_log_lsm_data(ab, &request->audit);
	audit_log_end(ab);

	/* Logs this domain the first time it shows in log. */
	log_domain(youngest_denied);
}

/**
 * landlock_log_drop_domain - Create an audit record on domain deallocation
 *
 * @hierarchy: The domain's hierarchy being deallocated.
 *
 * Only domains which previously appeared in the audit logs are logged again.
 * This is useful to know when a domain will never show again in the audit log.
 *
 * Called in a work queue scheduled by landlock_put_ruleset_deferred() called
 * by hook_cred_free().
 */
void landlock_log_drop_domain(const struct landlock_hierarchy *const hierarchy)
{
	struct audit_buffer *ab;

	if (WARN_ON_ONCE(!hierarchy))
		return;

	if (!audit_enabled)
		return;

	/* Ignores domains that were not logged.  */
	if (READ_ONCE(hierarchy->log_status) != LANDLOCK_LOG_RECORDED)
		return;

	/*
	 * If logging of domain allocation succeeded, warns about failure to log
	 * domain deallocation to highlight unbalanced domain lifetime logs.
	 */
	ab = audit_log_start(audit_context(), GFP_KERNEL,
			     AUDIT_LANDLOCK_DOMAIN);
	if (!ab)
		return;

	audit_log_format(ab, "domain=%llx status=deallocated denials=%llu",
			 hierarchy->id, atomic64_read(&hierarchy->num_denials));
	audit_log_end(ab);
}

#ifdef CONFIG_SECURITY_LANDLOCK_KUNIT_TEST

static struct kunit_case test_cases[] = {
	/* clang-format off */
	KUNIT_CASE(test_get_hierarchy),
	KUNIT_CASE(test_get_denied_layer),
	KUNIT_CASE(test_get_layer_from_deny_masks),
	{}
	/* clang-format on */
};

static struct kunit_suite test_suite = {
	.name = "landlock_audit",
	.test_cases = test_cases,
};

kunit_test_suite(test_suite);

#endif /* CONFIG_SECURITY_LANDLOCK_KUNIT_TEST */
