// SPDX-License-Identifier: GPL-2.0
/*
 * Landlock tests - Signal Scoping
 *
 * Copyright © 2024 Tahera Fahimi <fahimitahera@gmail.com>
 */

#define _GNU_SOURCE
#include <errno.h>
#include <fcntl.h>
#include <linux/landlock.h>
#include <pthread.h>
#include <signal.h>
#include <sys/prctl.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>

#include "common.h"
#include "scoped_common.h"

/* This variable is used for handling several signals. */
static volatile sig_atomic_t is_signaled;

/* clang-format off */
FIXTURE(scoping_signals) {};
/* clang-format on */

FIXTURE_VARIANT(scoping_signals)
{
	int sig;
};

/* clang-format off */
FIXTURE_VARIANT_ADD(scoping_signals, sigtrap) {
	/* clang-format on */
	.sig = SIGTRAP,
};

/* clang-format off */
FIXTURE_VARIANT_ADD(scoping_signals, sigurg) {
	/* clang-format on */
	.sig = SIGURG,
};

/* clang-format off */
FIXTURE_VARIANT_ADD(scoping_signals, sighup) {
	/* clang-format on */
	.sig = SIGHUP,
};

/* clang-format off */
FIXTURE_VARIANT_ADD(scoping_signals, sigtstp) {
	/* clang-format on */
	.sig = SIGTSTP,
};

FIXTURE_SETUP(scoping_signals)
{
	drop_caps(_metadata);

	is_signaled = 0;
}

FIXTURE_TEARDOWN(scoping_signals)
{
}

static void scope_signal_handler(int sig, siginfo_t *info, void *ucontext)
{
	if (sig == SIGTRAP || sig == SIGURG || sig == SIGHUP || sig == SIGTSTP)
		is_signaled = 1;
}

/*
 * In this test, a child process sends a signal to parent before and
 * after getting scoped.
 */
TEST_F(scoping_signals, send_sig_to_parent)
{
	int pipe_parent[2];
	int status;
	pid_t child;
	pid_t parent = getpid();
	struct sigaction action = {
		.sa_sigaction = scope_signal_handler,
		.sa_flags = SA_SIGINFO,

	};

	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
	ASSERT_LE(0, sigaction(variant->sig, &action, NULL));

	/* The process should not have already been signaled. */
	EXPECT_EQ(0, is_signaled);

	child = fork();
	ASSERT_LE(0, child);
	if (child == 0) {
		char buf_child;
		int err;

		EXPECT_EQ(0, close(pipe_parent[1]));

		/*
		 * The child process can send signal to parent when
		 * domain is not scoped.
		 */
		err = kill(parent, variant->sig);
		ASSERT_EQ(0, err);
		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
		EXPECT_EQ(0, close(pipe_parent[0]));

		create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

		/*
		 * The child process cannot send signal to the parent
		 * anymore.
		 */
		err = kill(parent, variant->sig);
		ASSERT_EQ(-1, err);
		ASSERT_EQ(EPERM, errno);

		/*
		 * No matter of the domain, a process should be able to
		 * send a signal to itself.
		 */
		ASSERT_EQ(0, is_signaled);
		ASSERT_EQ(0, raise(variant->sig));
		ASSERT_EQ(1, is_signaled);

		_exit(_metadata->exit_code);
		return;
	}
	EXPECT_EQ(0, close(pipe_parent[0]));

	/* Waits for a first signal to be received, without race condition. */
	while (!is_signaled && !usleep(1))
		;
	ASSERT_EQ(1, is_signaled);
	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
	EXPECT_EQ(0, close(pipe_parent[1]));
	is_signaled = 0;

	ASSERT_EQ(child, waitpid(child, &status, 0));
	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
	    WEXITSTATUS(status) != EXIT_SUCCESS)
		_metadata->exit_code = KSFT_FAIL;

	EXPECT_EQ(0, is_signaled);
}

/* clang-format off */
FIXTURE(scoped_domains) {};
/* clang-format on */

#include "scoped_base_variants.h"

FIXTURE_SETUP(scoped_domains)
{
	drop_caps(_metadata);
}

FIXTURE_TEARDOWN(scoped_domains)
{
}

/*
 * This test ensures that a scoped process cannot send signal out of
 * scoped domain.
 */
TEST_F(scoped_domains, check_access_signal)
{
	pid_t child;
	pid_t parent = getpid();
	int status;
	bool can_signal_child, can_signal_parent;
	int pipe_parent[2], pipe_child[2];
	char buf_parent;
	int err;

	can_signal_parent = !variant->domain_child;
	can_signal_child = !variant->domain_parent;

	if (variant->domain_both)
		create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));

	child = fork();
	ASSERT_LE(0, child);
	if (child == 0) {
		char buf_child;

		EXPECT_EQ(0, close(pipe_child[0]));
		EXPECT_EQ(0, close(pipe_parent[1]));

		if (variant->domain_child)
			create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
		EXPECT_EQ(0, close(pipe_child[1]));

		/* Waits for the parent to send signals. */
		ASSERT_EQ(1, read(pipe_parent[0], &buf_child, 1));
		EXPECT_EQ(0, close(pipe_parent[0]));

		err = kill(parent, 0);
		if (can_signal_parent) {
			ASSERT_EQ(0, err);
		} else {
			ASSERT_EQ(-1, err);
			ASSERT_EQ(EPERM, errno);
		}
		/*
		 * No matter of the domain, a process should be able to
		 * send a signal to itself.
		 */
		ASSERT_EQ(0, raise(0));

		_exit(_metadata->exit_code);
		return;
	}
	EXPECT_EQ(0, close(pipe_parent[0]));
	EXPECT_EQ(0, close(pipe_child[1]));

	if (variant->domain_parent)
		create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

	ASSERT_EQ(1, read(pipe_child[0], &buf_parent, 1));
	EXPECT_EQ(0, close(pipe_child[0]));

	err = kill(child, 0);
	if (can_signal_child) {
		ASSERT_EQ(0, err);
	} else {
		ASSERT_EQ(-1, err);
		ASSERT_EQ(EPERM, errno);
	}
	ASSERT_EQ(0, raise(0));

	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
	EXPECT_EQ(0, close(pipe_parent[1]));
	ASSERT_EQ(child, waitpid(child, &status, 0));

	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
	    WEXITSTATUS(status) != EXIT_SUCCESS)
		_metadata->exit_code = KSFT_FAIL;
}

static int thread_pipe[2];

enum thread_return {
	THREAD_INVALID = 0,
	THREAD_SUCCESS = 1,
	THREAD_ERROR = 2,
};

void *thread_func(void *arg)
{
	char buf;

	if (read(thread_pipe[0], &buf, 1) != 1)
		return (void *)THREAD_ERROR;

	return (void *)THREAD_SUCCESS;
}

TEST(signal_scoping_threads)
{
	pthread_t no_sandbox_thread, scoped_thread;
	enum thread_return ret = THREAD_INVALID;

	drop_caps(_metadata);
	ASSERT_EQ(0, pipe2(thread_pipe, O_CLOEXEC));

	ASSERT_EQ(0,
		  pthread_create(&no_sandbox_thread, NULL, thread_func, NULL));

	/* Restricts the domain after creating the first thread. */
	create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

	ASSERT_EQ(EPERM, pthread_kill(no_sandbox_thread, 0));
	ASSERT_EQ(1, write(thread_pipe[1], ".", 1));

	ASSERT_EQ(0, pthread_create(&scoped_thread, NULL, thread_func, NULL));
	ASSERT_EQ(0, pthread_kill(scoped_thread, 0));
	ASSERT_EQ(1, write(thread_pipe[1], ".", 1));

	EXPECT_EQ(0, pthread_join(no_sandbox_thread, (void **)&ret));
	EXPECT_EQ(THREAD_SUCCESS, ret);
	EXPECT_EQ(0, pthread_join(scoped_thread, (void **)&ret));
	EXPECT_EQ(THREAD_SUCCESS, ret);

	EXPECT_EQ(0, close(thread_pipe[0]));
	EXPECT_EQ(0, close(thread_pipe[1]));
}

const short backlog = 10;

static volatile sig_atomic_t signal_received;

static void handle_sigurg(int sig)
{
	if (sig == SIGURG)
		signal_received = 1;
	else
		signal_received = -1;
}

static int setup_signal_handler(int signal)
{
	struct sigaction sa = {
		.sa_handler = handle_sigurg,
	};

	if (sigemptyset(&sa.sa_mask))
		return -1;

	sa.sa_flags = SA_SIGINFO | SA_RESTART;
	return sigaction(SIGURG, &sa, NULL);
}

/* clang-format off */
FIXTURE(fown) {};
/* clang-format on */

enum fown_sandbox {
	SANDBOX_NONE,
	SANDBOX_BEFORE_FORK,
	SANDBOX_BEFORE_SETOWN,
	SANDBOX_AFTER_SETOWN,
};

FIXTURE_VARIANT(fown)
{
	const enum fown_sandbox sandbox_setown;
};

/* clang-format off */
FIXTURE_VARIANT_ADD(fown, no_sandbox) {
	/* clang-format on */
	.sandbox_setown = SANDBOX_NONE,
};

/* clang-format off */
FIXTURE_VARIANT_ADD(fown, sandbox_before_fork) {
	/* clang-format on */
	.sandbox_setown = SANDBOX_BEFORE_FORK,
};

/* clang-format off */
FIXTURE_VARIANT_ADD(fown, sandbox_before_setown) {
	/* clang-format on */
	.sandbox_setown = SANDBOX_BEFORE_SETOWN,
};

/* clang-format off */
FIXTURE_VARIANT_ADD(fown, sandbox_after_setown) {
	/* clang-format on */
	.sandbox_setown = SANDBOX_AFTER_SETOWN,
};

FIXTURE_SETUP(fown)
{
	drop_caps(_metadata);
}

FIXTURE_TEARDOWN(fown)
{
}

/*
 * Sending an out of bound message will trigger the SIGURG signal
 * through file_send_sigiotask.
 */
TEST_F(fown, sigurg_socket)
{
	int server_socket, recv_socket;
	struct service_fixture server_address;
	char buffer_parent;
	int status;
	int pipe_parent[2], pipe_child[2];
	pid_t child;

	memset(&server_address, 0, sizeof(server_address));
	set_unix_address(&server_address, 0);

	ASSERT_EQ(0, pipe2(pipe_parent, O_CLOEXEC));
	ASSERT_EQ(0, pipe2(pipe_child, O_CLOEXEC));

	if (variant->sandbox_setown == SANDBOX_BEFORE_FORK)
		create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

	child = fork();
	ASSERT_LE(0, child);
	if (child == 0) {
		int client_socket;
		char buffer_child;

		EXPECT_EQ(0, close(pipe_parent[1]));
		EXPECT_EQ(0, close(pipe_child[0]));

		ASSERT_EQ(0, setup_signal_handler(SIGURG));
		client_socket = socket(AF_UNIX, SOCK_STREAM, 0);
		ASSERT_LE(0, client_socket);

		/* Waits for the parent to listen. */
		ASSERT_EQ(1, read(pipe_parent[0], &buffer_child, 1));
		ASSERT_EQ(0, connect(client_socket, &server_address.unix_addr,
				     server_address.unix_addr_len));

		/*
		 * Waits for the parent to accept the connection, sandbox
		 * itself, and call fcntl(2).
		 */
		ASSERT_EQ(1, read(pipe_parent[0], &buffer_child, 1));
		/* May signal itself. */
		ASSERT_EQ(1, send(client_socket, ".", 1, MSG_OOB));
		EXPECT_EQ(0, close(client_socket));
		ASSERT_EQ(1, write(pipe_child[1], ".", 1));
		EXPECT_EQ(0, close(pipe_child[1]));

		/* Waits for the message to be received. */
		ASSERT_EQ(1, read(pipe_parent[0], &buffer_child, 1));
		EXPECT_EQ(0, close(pipe_parent[0]));

		if (variant->sandbox_setown == SANDBOX_BEFORE_SETOWN) {
			ASSERT_EQ(0, signal_received);
		} else {
			/*
			 * A signal is only received if fcntl(F_SETOWN) was
			 * called before any sandboxing or if the signal
			 * receiver is in the same domain.
			 */
			ASSERT_EQ(1, signal_received);
		}
		_exit(_metadata->exit_code);
		return;
	}
	EXPECT_EQ(0, close(pipe_parent[0]));
	EXPECT_EQ(0, close(pipe_child[1]));

	server_socket = socket(AF_UNIX, SOCK_STREAM, 0);
	ASSERT_LE(0, server_socket);
	ASSERT_EQ(0, bind(server_socket, &server_address.unix_addr,
			  server_address.unix_addr_len));
	ASSERT_EQ(0, listen(server_socket, backlog));
	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));

	recv_socket = accept(server_socket, NULL, NULL);
	ASSERT_LE(0, recv_socket);

	if (variant->sandbox_setown == SANDBOX_BEFORE_SETOWN)
		create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

	/*
	 * Sets the child to receive SIGURG for MSG_OOB.  This uncommon use is
	 * a valid attack scenario which also simplifies this test.
	 */
	ASSERT_EQ(0, fcntl(recv_socket, F_SETOWN, child));

	if (variant->sandbox_setown == SANDBOX_AFTER_SETOWN)
		create_scoped_domain(_metadata, LANDLOCK_SCOPE_SIGNAL);

	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));

	/* Waits for the child to send MSG_OOB. */
	ASSERT_EQ(1, read(pipe_child[0], &buffer_parent, 1));
	EXPECT_EQ(0, close(pipe_child[0]));
	ASSERT_EQ(1, recv(recv_socket, &buffer_parent, 1, MSG_OOB));
	EXPECT_EQ(0, close(recv_socket));
	EXPECT_EQ(0, close(server_socket));
	ASSERT_EQ(1, write(pipe_parent[1], ".", 1));
	EXPECT_EQ(0, close(pipe_parent[1]));

	ASSERT_EQ(child, waitpid(child, &status, 0));
	if (WIFSIGNALED(status) || !WIFEXITED(status) ||
	    WEXITSTATUS(status) != EXIT_SUCCESS)
		_metadata->exit_code = KSFT_FAIL;
}

TEST_HARNESS_MAIN
