// SPDX-License-Identifier: GPL-2.0-only
/*
 * Landlock - Ptrace and scope hooks
 *
 * Copyright © 2017-2020 Mickaël Salaün <mic@digikod.net>
 * Copyright © 2019-2020 ANSSI
 * Copyright © 2024-2025 Microsoft Corporation
 */

#include <asm/current.h>
#include <linux/cleanup.h>
#include <linux/cred.h>
#include <linux/errno.h>
#include <linux/kernel.h>
#include <linux/lsm_audit.h>
#include <linux/lsm_hooks.h>
#include <linux/rcupdate.h>
#include <linux/sched.h>
#include <linux/sched/signal.h>
#include <net/af_unix.h>
#include <net/sock.h>

#include "audit.h"
#include "common.h"
#include "cred.h"
#include "domain.h"
#include "fs.h"
#include "ruleset.h"
#include "setup.h"
#include "task.h"

/**
 * domain_scope_le - Checks domain ordering for scoped ptrace
 *
 * @parent: Parent domain.
 * @child: Potential child of @parent.
 *
 * Checks if the @parent domain is less or equal to (i.e. an ancestor, which
 * means a subset of) the @child domain.
 *
 * Return: True if @parent is an ancestor of or equal to @child, false
 * otherwise.
 */
static bool domain_scope_le(const struct landlock_ruleset *const parent,
			    const struct landlock_ruleset *const child)
{
	const struct landlock_hierarchy *walker;

	/* Quick return for non-landlocked tasks. */
	if (!parent)
		return true;

	if (!child)
		return false;

	for (walker = child->hierarchy; walker; walker = walker->parent) {
		if (walker == parent->hierarchy)
			/* @parent is in the scoped hierarchy of @child. */
			return true;
	}

	/* There is no relationship between @parent and @child. */
	return false;
}

static int domain_ptrace(const struct landlock_ruleset *const parent,
			 const struct landlock_ruleset *const child)
{
	if (domain_scope_le(parent, child))
		return 0;

	return -EPERM;
}

/**
 * hook_ptrace_access_check - Determines whether the current process may access
 *			      another
 *
 * @child: Process to be accessed.
 * @mode: Mode of attachment.
 *
 * If the current task has Landlock rules, then the child must have at least
 * the same rules.  Else denied.
 *
 * Return: 0 if permission is granted, -errno if denied.
 */
static int hook_ptrace_access_check(struct task_struct *const child,
				    const unsigned int mode)
{
	const struct landlock_cred_security *parent_subject;
	int err;

	/* Quick return for non-landlocked tasks. */
	parent_subject = landlock_cred(current_cred());
	if (!parent_subject)
		return 0;

	scoped_guard(rcu)
	{
		const struct landlock_ruleset *const child_dom =
			landlock_get_task_domain(child);
		err = domain_ptrace(parent_subject->domain, child_dom);
	}

	if (!err)
		return 0;

	/*
	 * For the ptrace_access_check case, we log the current/parent domain
	 * and the child task.
	 */
	if (!(mode & PTRACE_MODE_NOAUDIT))
		landlock_log_denial(parent_subject, &(struct landlock_request) {
			.type = LANDLOCK_REQUEST_PTRACE,
			.audit = {
				.type = LSM_AUDIT_DATA_TASK,
				.u.tsk = child,
			},
			.layer_plus_one = parent_subject->domain->num_layers,
		});

	return err;
}

/**
 * hook_ptrace_traceme - Determines whether another process may trace the
 *			 current one
 *
 * @parent: Task proposed to be the tracer.
 *
 * If the parent has Landlock rules, then the current task must have the same
 * or more rules.  Else denied.
 *
 * Return: 0 if permission is granted, -errno if denied.
 */
static int hook_ptrace_traceme(struct task_struct *const parent)
{
	const struct landlock_cred_security *parent_subject;
	const struct landlock_ruleset *child_dom;
	int err;

	child_dom = landlock_get_current_domain();

	guard(rcu)();
	parent_subject = landlock_cred(__task_cred(parent));
	err = domain_ptrace(parent_subject->domain, child_dom);

	if (!err)
		return 0;

	/*
	 * For the ptrace_traceme case, we log the domain which is the cause of
	 * the denial, which means the parent domain instead of the current
	 * domain.  This may look unusual because the ptrace_traceme action is a
	 * request to be traced, but the semantic is consistent with
	 * hook_ptrace_access_check().
	 */
	landlock_log_denial(parent_subject, &(struct landlock_request) {
		.type = LANDLOCK_REQUEST_PTRACE,
		.audit = {
			.type = LSM_AUDIT_DATA_TASK,
			.u.tsk = current,
		},
		.layer_plus_one = parent_subject->domain->num_layers,
	});
	return err;
}

/**
 * domain_is_scoped - Check if an interaction from a client/sender to a
 *		      server/receiver should be restricted based on scope controls.
 *
 * @client: IPC sender domain.
 * @server: IPC receiver domain.
 * @scope: The scope restriction criteria.
 *
 * Return: True if @server is in a different domain from @client and @client
 * is scoped to access @server (i.e. access should be denied), false otherwise.
 */
static bool domain_is_scoped(const struct landlock_ruleset *const client,
			     const struct landlock_ruleset *const server,
			     access_mask_t scope)
{
	int client_layer, server_layer;
	const struct landlock_hierarchy *client_walker, *server_walker;

	/* Quick return if client has no domain */
	if (WARN_ON_ONCE(!client))
		return false;

	client_layer = client->num_layers - 1;
	client_walker = client->hierarchy;
	/*
	 * client_layer must be able to represent all numbers from
	 * LANDLOCK_MAX_NUM_LAYERS - 1 to -1 for the loop below to terminate.
	 * (It must be large enough, and it must be signed.)
	 */
	BUILD_BUG_ON(!is_signed_type(typeof(client_layer)));
	BUILD_BUG_ON(LANDLOCK_MAX_NUM_LAYERS - 1 >
		     type_max(typeof(client_layer)));

	server_layer = server ? (server->num_layers - 1) : -1;
	server_walker = server ? server->hierarchy : NULL;

	/*
	 * Walks client's parent domains down to the same hierarchy level
	 * as the server's domain, and checks that none of these client's
	 * parent domains are scoped.
	 */
	for (; client_layer > server_layer; client_layer--) {
		if (landlock_get_scope_mask(client, client_layer) & scope)
			return true;

		client_walker = client_walker->parent;
	}
	/*
	 * Walks server's parent domains down to the same hierarchy level as
	 * the client's domain.
	 */
	for (; server_layer > client_layer; server_layer--)
		server_walker = server_walker->parent;

	for (; client_layer >= 0; client_layer--) {
		if (landlock_get_scope_mask(client, client_layer) & scope) {
			/*
			 * Client and server are at the same level in the
			 * hierarchy. If the client is scoped, the request is
			 * only allowed if this domain is also a server's
			 * ancestor.
			 */
			return server_walker != client_walker;
		}
		client_walker = client_walker->parent;
		server_walker = server_walker->parent;
	}
	return false;
}

static bool sock_is_scoped(struct sock *const other,
			   const struct landlock_ruleset *const domain)
{
	const struct landlock_ruleset *dom_other;

	/* The credentials will not change. */
	lockdep_assert_held(&unix_sk(other)->lock);
	dom_other = landlock_cred(other->sk_socket->file->f_cred)->domain;
	return domain_is_scoped(domain, dom_other,
				LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET);
}

static bool is_abstract_socket(struct sock *const sock)
{
	struct unix_address *addr = unix_sk(sock)->addr;

	if (!addr)
		return false;

	if (addr->len >= offsetof(struct sockaddr_un, sun_path) + 1 &&
	    addr->name->sun_path[0] == '\0')
		return true;

	return false;
}

static const struct access_masks unix_scope = {
	.scope = LANDLOCK_SCOPE_ABSTRACT_UNIX_SOCKET,
};

static int hook_unix_stream_connect(struct sock *const sock,
				    struct sock *const other,
				    struct sock *const newsk)
{
	size_t handle_layer;
	const struct landlock_cred_security *const subject =
		landlock_get_applicable_subject(current_cred(), unix_scope,
						&handle_layer);

	/* Quick return for non-landlocked tasks. */
	if (!subject)
		return 0;

	if (!is_abstract_socket(other))
		return 0;

	if (!sock_is_scoped(other, subject->domain))
		return 0;

	landlock_log_denial(subject, &(struct landlock_request) {
		.type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
		.audit = {
			.type = LSM_AUDIT_DATA_NET,
			.u.net = &(struct lsm_network_audit) {
				.sk = other,
			},
		},
		.layer_plus_one = handle_layer + 1,
	});
	return -EPERM;
}

static int hook_unix_may_send(struct socket *const sock,
			      struct socket *const other)
{
	size_t handle_layer;
	const struct landlock_cred_security *const subject =
		landlock_get_applicable_subject(current_cred(), unix_scope,
						&handle_layer);

	if (!subject)
		return 0;

	/*
	 * Checks if this datagram socket was already allowed to be connected
	 * to other.
	 */
	if (unix_peer(sock->sk) == other->sk)
		return 0;

	if (!is_abstract_socket(other->sk))
		return 0;

	if (!sock_is_scoped(other->sk, subject->domain))
		return 0;

	landlock_log_denial(subject, &(struct landlock_request) {
		.type = LANDLOCK_REQUEST_SCOPE_ABSTRACT_UNIX_SOCKET,
		.audit = {
			.type = LSM_AUDIT_DATA_NET,
			.u.net = &(struct lsm_network_audit) {
				.sk = other->sk,
			},
		},
		.layer_plus_one = handle_layer + 1,
	});
	return -EPERM;
}

static const struct access_masks signal_scope = {
	.scope = LANDLOCK_SCOPE_SIGNAL,
};

static int hook_task_kill(struct task_struct *const p,
			  struct kernel_siginfo *const info, const int sig,
			  const struct cred *cred)
{
	bool is_scoped;
	size_t handle_layer;
	const struct landlock_cred_security *subject;

	if (!cred) {
		/*
		 * Always allow sending signals between threads of the same process.
		 * This is required for process credential changes by the Native POSIX
		 * Threads Library and implemented by the set*id(2) wrappers and
		 * libcap(3) with tgkill(2).  See nptl(7) and libpsx(3).
		 *
		 * This exception is similar to the __ptrace_may_access() one.
		 */
		if (same_thread_group(p, current))
			return 0;

		/* Not dealing with USB IO. */
		cred = current_cred();
	}

	subject = landlock_get_applicable_subject(cred, signal_scope,
						  &handle_layer);

	/* Quick return for non-landlocked tasks. */
	if (!subject)
		return 0;

	scoped_guard(rcu)
	{
		is_scoped = domain_is_scoped(subject->domain,
					     landlock_get_task_domain(p),
					     signal_scope.scope);
	}

	if (!is_scoped)
		return 0;

	landlock_log_denial(subject, &(struct landlock_request) {
		.type = LANDLOCK_REQUEST_SCOPE_SIGNAL,
		.audit = {
			.type = LSM_AUDIT_DATA_TASK,
			.u.tsk = p,
		},
		.layer_plus_one = handle_layer + 1,
	});
	return -EPERM;
}

static int hook_file_send_sigiotask(struct task_struct *tsk,
				    struct fown_struct *fown, int signum)
{
	const struct landlock_cred_security *subject;
	bool is_scoped = false;

	/* Lock already held by send_sigio() and send_sigurg(). */
	lockdep_assert_held(&fown->lock);
	subject = &landlock_file(fown->file)->fown_subject;

	/*
	 * Quick return for unowned socket.
	 *
	 * subject->domain has already been filtered when saved by
	 * hook_file_set_fowner(), so there is no need to call
	 * landlock_get_applicable_subject() here.
	 */
	if (!subject->domain)
		return 0;

	scoped_guard(rcu)
	{
		is_scoped = domain_is_scoped(subject->domain,
					     landlock_get_task_domain(tsk),
					     signal_scope.scope);
	}

	if (!is_scoped)
		return 0;

	landlock_log_denial(subject, &(struct landlock_request) {
		.type = LANDLOCK_REQUEST_SCOPE_SIGNAL,
		.audit = {
			.type = LSM_AUDIT_DATA_TASK,
			.u.tsk = tsk,
		},
#ifdef CONFIG_AUDIT
		.layer_plus_one = landlock_file(fown->file)->fown_layer + 1,
#endif /* CONFIG_AUDIT */
	});
	return -EPERM;
}

static struct security_hook_list landlock_hooks[] __ro_after_init = {
	LSM_HOOK_INIT(ptrace_access_check, hook_ptrace_access_check),
	LSM_HOOK_INIT(ptrace_traceme, hook_ptrace_traceme),

	LSM_HOOK_INIT(unix_stream_connect, hook_unix_stream_connect),
	LSM_HOOK_INIT(unix_may_send, hook_unix_may_send),

	LSM_HOOK_INIT(task_kill, hook_task_kill),
	LSM_HOOK_INIT(file_send_sigiotask, hook_file_send_sigiotask),
};

__init void landlock_add_task_hooks(void)
{
	security_add_hooks(landlock_hooks, ARRAY_SIZE(landlock_hooks),
			   &landlock_lsmid);
}
