// SPDX-License-Identifier: GPL-2.0
/*
 * Tests Memory Protection Keys (see Documentation/core-api/protection-keys.rst)
 *
 * The testcases in this file exercise various flows related to signal handling,
 * using an alternate signal stack, with the default pkey (pkey 0) disabled.
 *
 * Compile with:
 * gcc -mxsave      -o pkey_sighandler_tests -O2 -g -std=gnu99 -pthread -Wall pkey_sighandler_tests.c -I../../../../tools/include -lrt -ldl -lm
 * gcc -mxsave -m32 -o pkey_sighandler_tests -O2 -g -std=gnu99 -pthread -Wall pkey_sighandler_tests.c -I../../../../tools/include -lrt -ldl -lm
 */
#define _GNU_SOURCE
#define __SANE_USERSPACE_TYPES__
#include <errno.h>
#include <sys/syscall.h>
#include <string.h>
#include <stdio.h>
#include <stdint.h>
#include <stdbool.h>
#include <signal.h>
#include <assert.h>
#include <stdlib.h>
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <pthread.h>
#include <limits.h>

#include "pkey-helpers.h"

#define STACK_SIZE PTHREAD_STACK_MIN

void expected_pkey_fault(int pkey) {}

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
siginfo_t siginfo = {0};

/*
 * We need to use inline assembly instead of glibc's syscall because glibc's
 * syscall will attempt to access the PLT in order to call a library function
 * which is protected by MPK 0 which we don't have access to.
 */
static inline __always_inline
long syscall_raw(long n, long a1, long a2, long a3, long a4, long a5, long a6)
{
	unsigned long ret;
#ifdef __x86_64__
	register long r10 asm("r10") = a4;
	register long r8 asm("r8") = a5;
	register long r9 asm("r9") = a6;
	asm volatile ("syscall"
		      : "=a"(ret)
		      : "a"(n), "D"(a1), "S"(a2), "d"(a3), "r"(r10), "r"(r8), "r"(r9)
		      : "rcx", "r11", "memory");
#elif defined __i386__
	asm volatile ("int $0x80"
		      : "=a"(ret)
		      : "a"(n), "b"(a1), "c"(a2), "d"(a3), "S"(a4), "D"(a5)
		      : "memory");
#else
# error syscall_raw() not implemented
#endif
	return ret;
}

static void sigsegv_handler(int signo, siginfo_t *info, void *ucontext)
{
	pthread_mutex_lock(&mutex);

	memcpy(&siginfo, info, sizeof(siginfo_t));

	pthread_cond_signal(&cond);
	pthread_mutex_unlock(&mutex);

	syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
}

static void sigusr1_handler(int signo, siginfo_t *info, void *ucontext)
{
	pthread_mutex_lock(&mutex);

	memcpy(&siginfo, info, sizeof(siginfo_t));

	pthread_cond_signal(&cond);
	pthread_mutex_unlock(&mutex);
}

static void sigusr2_handler(int signo, siginfo_t *info, void *ucontext)
{
	/*
	 * pkru should be the init_pkru value which enabled MPK 0 so
	 * we can use library functions.
	 */
	printf("%s invoked.\n", __func__);
}

static void raise_sigusr2(void)
{
	pid_t tid = 0;

	tid = syscall_raw(SYS_gettid, 0, 0, 0, 0, 0, 0);

	syscall_raw(SYS_tkill, tid, SIGUSR2, 0, 0, 0, 0);

	/*
	 * We should return from the signal handler here and be able to
	 * return to the interrupted thread.
	 */
}

static void *thread_segv_with_pkey0_disabled(void *ptr)
{
	/* Disable MPK 0 (and all others too) */
	__write_pkey_reg(0x55555555);

	/* Segfault (with SEGV_MAPERR) */
	*(int *) (0x1) = 1;
	return NULL;
}

static void *thread_segv_pkuerr_stack(void *ptr)
{
	/* Disable MPK 0 (and all others too) */
	__write_pkey_reg(0x55555555);

	/* After we disable MPK 0, we can't access the stack to return */
	return NULL;
}

static void *thread_segv_maperr_ptr(void *ptr)
{
	stack_t *stack = ptr;
	int *bad = (int *)1;

	/*
	 * Setup alternate signal stack, which should be pkey_mprotect()ed by
	 * MPK 0. The thread's stack cannot be used for signals because it is
	 * not accessible by the default init_pkru value of 0x55555554.
	 */
	syscall_raw(SYS_sigaltstack, (long)stack, 0, 0, 0, 0, 0);

	/* Disable MPK 0.  Only MPK 1 is enabled. */
	__write_pkey_reg(0x55555551);

	/* Segfault */
	*bad = 1;
	syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
	return NULL;
}

/*
 * Verify that the sigsegv handler is invoked when pkey 0 is disabled.
 * Note that the new thread stack and the alternate signal stack is
 * protected by MPK 0.
 */
static void test_sigsegv_handler_with_pkey0_disabled(void)
{
	struct sigaction sa;
	pthread_attr_t attr;
	pthread_t thr;

	sa.sa_flags = SA_SIGINFO;

	sa.sa_sigaction = sigsegv_handler;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGSEGV, &sa, NULL) == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	memset(&siginfo, 0, sizeof(siginfo));

	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	pthread_create(&thr, &attr, thread_segv_with_pkey0_disabled, NULL);

	pthread_mutex_lock(&mutex);
	while (siginfo.si_signo == 0)
		pthread_cond_wait(&cond, &mutex);
	pthread_mutex_unlock(&mutex);

	ksft_test_result(siginfo.si_signo == SIGSEGV &&
			 siginfo.si_code == SEGV_MAPERR &&
			 siginfo.si_addr == (void *)1,
			 "%s\n", __func__);
}

/*
 * Verify that the sigsegv handler is invoked when pkey 0 is disabled.
 * Note that the new thread stack and the alternate signal stack is
 * protected by MPK 0, which renders them inaccessible when MPK 0
 * is disabled. So just the return from the thread should cause a
 * segfault with SEGV_PKUERR.
 */
static void test_sigsegv_handler_cannot_access_stack(void)
{
	struct sigaction sa;
	pthread_attr_t attr;
	pthread_t thr;

	sa.sa_flags = SA_SIGINFO;

	sa.sa_sigaction = sigsegv_handler;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGSEGV, &sa, NULL) == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	memset(&siginfo, 0, sizeof(siginfo));

	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);

	pthread_create(&thr, &attr, thread_segv_pkuerr_stack, NULL);

	pthread_mutex_lock(&mutex);
	while (siginfo.si_signo == 0)
		pthread_cond_wait(&cond, &mutex);
	pthread_mutex_unlock(&mutex);

	ksft_test_result(siginfo.si_signo == SIGSEGV &&
			 siginfo.si_code == SEGV_PKUERR,
			 "%s\n", __func__);
}

/*
 * Verify that the sigsegv handler that uses an alternate signal stack
 * is correctly invoked for a thread which uses a non-zero MPK to protect
 * its own stack, and disables all other MPKs (including 0).
 */
static void test_sigsegv_handler_with_different_pkey_for_stack(void)
{
	struct sigaction sa;
	static stack_t sigstack;
	void *stack;
	int pkey;
	int parent_pid = 0;
	int child_pid = 0;

	sa.sa_flags = SA_SIGINFO | SA_ONSTACK;

	sa.sa_sigaction = sigsegv_handler;

	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGSEGV, &sa, NULL) == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	stack = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE,
		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

	assert(stack != MAP_FAILED);

	/* Allow access to MPK 0 and MPK 1 */
	__write_pkey_reg(0x55555550);

	/* Protect the new stack with MPK 1 */
	pkey = pkey_alloc(0, 0);
	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);

	/* Set up alternate signal stack that will use the default MPK */
	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	sigstack.ss_flags = 0;
	sigstack.ss_size = STACK_SIZE;

	memset(&siginfo, 0, sizeof(siginfo));

	/* Use clone to avoid newer glibcs using rseq on new threads */
	long ret = syscall_raw(SYS_clone,
			       CLONE_VM | CLONE_FS | CLONE_FILES |
			       CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
			       CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
			       CLONE_DETACHED,
			       (long) ((char *)(stack) + STACK_SIZE),
			       (long) &parent_pid,
			       (long) &child_pid, 0, 0);

	if (ret < 0) {
		errno = -ret;
		perror("clone");
	} else if (ret == 0) {
		thread_segv_maperr_ptr(&sigstack);
		syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
	}

	pthread_mutex_lock(&mutex);
	while (siginfo.si_signo == 0)
		pthread_cond_wait(&cond, &mutex);
	pthread_mutex_unlock(&mutex);

	ksft_test_result(siginfo.si_signo == SIGSEGV &&
			 siginfo.si_code == SEGV_MAPERR &&
			 siginfo.si_addr == (void *)1,
			 "%s\n", __func__);
}

/*
 * Verify that the PKRU value set by the application is correctly
 * restored upon return from signal handling.
 */
static void test_pkru_preserved_after_sigusr1(void)
{
	struct sigaction sa;
	unsigned long pkru = 0x45454544;

	sa.sa_flags = SA_SIGINFO;

	sa.sa_sigaction = sigusr1_handler;
	sigemptyset(&sa.sa_mask);
	if (sigaction(SIGUSR1, &sa, NULL) == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	memset(&siginfo, 0, sizeof(siginfo));

	__write_pkey_reg(pkru);

	raise(SIGUSR1);

	pthread_mutex_lock(&mutex);
	while (siginfo.si_signo == 0)
		pthread_cond_wait(&cond, &mutex);
	pthread_mutex_unlock(&mutex);

	/* Ensure the pkru value is the same after returning from signal. */
	ksft_test_result(pkru == __read_pkey_reg() &&
			 siginfo.si_signo == SIGUSR1,
			 "%s\n", __func__);
}

static noinline void *thread_sigusr2_self(void *ptr)
{
	/*
	 * A const char array like "Resuming after SIGUSR2" won't be stored on
	 * the stack and the code could access it via an offset from the program
	 * counter. This makes sure it's on the function's stack frame.
	 */
	char str[] = {'R', 'e', 's', 'u', 'm', 'i', 'n', 'g', ' ',
		'a', 'f', 't', 'e', 'r', ' ',
		'S', 'I', 'G', 'U', 'S', 'R', '2',
		'.', '.', '.', '\n', '\0'};
	stack_t *stack = ptr;

	/*
	 * Setup alternate signal stack, which should be pkey_mprotect()ed by
	 * MPK 0. The thread's stack cannot be used for signals because it is
	 * not accessible by the default init_pkru value of 0x55555554.
	 */
	syscall(SYS_sigaltstack, (long)stack, 0, 0, 0, 0, 0);

	/* Disable MPK 0.  Only MPK 2 is enabled. */
	__write_pkey_reg(0x55555545);

	raise_sigusr2();

	/* Do something, to show the thread resumed execution after the signal */
	syscall_raw(SYS_write, 1, (long) str, sizeof(str) - 1, 0, 0, 0);

	/*
	 * We can't return to test_pkru_sigreturn because it
	 * will attempt to use a %rbp value which is on the stack
	 * of the main thread.
	 */
	syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
	return NULL;
}

/*
 * Verify that sigreturn is able to restore altstack even if the thread had
 * disabled pkey 0.
 */
static void test_pkru_sigreturn(void)
{
	struct sigaction sa = {0};
	static stack_t sigstack;
	void *stack;
	int pkey;
	int parent_pid = 0;
	int child_pid = 0;

	sa.sa_handler = SIG_DFL;
	sa.sa_flags = 0;
	sigemptyset(&sa.sa_mask);

	/*
	 * For this testcase, we do not want to handle SIGSEGV. Reset handler
	 * to default so that the application can crash if it receives SIGSEGV.
	 */
	if (sigaction(SIGSEGV, &sa, NULL) == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	sa.sa_flags = SA_SIGINFO | SA_ONSTACK;
	sa.sa_sigaction = sigusr2_handler;
	sigemptyset(&sa.sa_mask);

	if (sigaction(SIGUSR2, &sa, NULL) == -1) {
		perror("sigaction");
		exit(EXIT_FAILURE);
	}

	stack = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE,
		     MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

	assert(stack != MAP_FAILED);

	/*
	 * Allow access to MPK 0 and MPK 2. The child thread (to be created
	 * later in this flow) will have its stack protected by MPK 2, whereas
	 * the current thread's stack is protected by the default MPK 0. Hence
	 * both need to be enabled.
	 */
	__write_pkey_reg(0x55555544);

	/* Protect the stack with MPK 2 */
	pkey = pkey_alloc(0, 0);
	pkey_mprotect(stack, STACK_SIZE, PROT_READ | PROT_WRITE, pkey);

	/* Set up alternate signal stack that will use the default MPK */
	sigstack.ss_sp = mmap(0, STACK_SIZE, PROT_READ | PROT_WRITE | PROT_EXEC,
			      MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
	sigstack.ss_flags = 0;
	sigstack.ss_size = STACK_SIZE;

	/* Use clone to avoid newer glibcs using rseq on new threads */
	long ret = syscall_raw(SYS_clone,
			       CLONE_VM | CLONE_FS | CLONE_FILES |
			       CLONE_SIGHAND | CLONE_THREAD | CLONE_SYSVSEM |
			       CLONE_PARENT_SETTID | CLONE_CHILD_CLEARTID |
			       CLONE_DETACHED,
			       (long) ((char *)(stack) + STACK_SIZE),
			       (long) &parent_pid,
			       (long) &child_pid, 0, 0);

	if (ret < 0) {
		errno = -ret;
		perror("clone");
	}  else if (ret == 0) {
		thread_sigusr2_self(&sigstack);
		syscall_raw(SYS_exit, 0, 0, 0, 0, 0, 0);
	}

	child_pid =  ret;
	/* Check that thread exited */
	do {
		sched_yield();
		ret = syscall_raw(SYS_tkill, child_pid, 0, 0, 0, 0, 0);
	} while (ret != -ESRCH && ret != -EINVAL);

	ksft_test_result_pass("%s\n", __func__);
}

static void (*pkey_tests[])(void) = {
	test_sigsegv_handler_with_pkey0_disabled,
	test_sigsegv_handler_cannot_access_stack,
	test_sigsegv_handler_with_different_pkey_for_stack,
	test_pkru_preserved_after_sigusr1,
	test_pkru_sigreturn
};

int main(int argc, char *argv[])
{
	int i;

	ksft_print_header();
	ksft_set_plan(ARRAY_SIZE(pkey_tests));

	for (i = 0; i < ARRAY_SIZE(pkey_tests); i++)
		(*pkey_tests[i])();

	ksft_finished();
	return 0;
}
