/*
 * ldt_gdt.c - Test cases for LDT and GDT access
 * Copyright (c) 2015 Andrew Lutomirski
 */

#define _GNU_SOURCE
#include <err.h>
#include <stdio.h>
#include <stdint.h>
#include <signal.h>
#include <setjmp.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <unistd.h>
#include <sys/syscall.h>
#include <asm/ldt.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <stdbool.h>
#include <pthread.h>
#include <sched.h>
#include <linux/futex.h>

#define AR_ACCESSED		(1<<8)

#define AR_TYPE_RODATA		(0 * (1<<9))
#define AR_TYPE_RWDATA		(1 * (1<<9))
#define AR_TYPE_RODATA_EXPDOWN	(2 * (1<<9))
#define AR_TYPE_RWDATA_EXPDOWN	(3 * (1<<9))
#define AR_TYPE_XOCODE		(4 * (1<<9))
#define AR_TYPE_XRCODE		(5 * (1<<9))
#define AR_TYPE_XOCODE_CONF	(6 * (1<<9))
#define AR_TYPE_XRCODE_CONF	(7 * (1<<9))

#define AR_DPL3			(3 * (1<<13))

#define AR_S			(1 << 12)
#define AR_P			(1 << 15)
#define AR_AVL			(1 << 20)
#define AR_L			(1 << 21)
#define AR_DB			(1 << 22)
#define AR_G			(1 << 23)

static int nerrs;

static void check_invalid_segment(uint16_t index, int ldt)
{
	uint32_t has_limit = 0, has_ar = 0, limit, ar;
	uint32_t selector = (index << 3) | (ldt << 2) | 3;

	asm ("lsl %[selector], %[limit]\n\t"
	     "jnz 1f\n\t"
	     "movl $1, %[has_limit]\n\t"
	     "1:"
	     : [limit] "=r" (limit), [has_limit] "+rm" (has_limit)
	     : [selector] "r" (selector));
	asm ("larl %[selector], %[ar]\n\t"
	     "jnz 1f\n\t"
	     "movl $1, %[has_ar]\n\t"
	     "1:"
	     : [ar] "=r" (ar), [has_ar] "+rm" (has_ar)
	     : [selector] "r" (selector));

	if (has_limit || has_ar) {
		printf("[FAIL]\t%s entry %hu is valid but should be invalid\n",
		       (ldt ? "LDT" : "GDT"), index);
		nerrs++;
	} else {
		printf("[OK]\t%s entry %hu is invalid\n",
		       (ldt ? "LDT" : "GDT"), index);
	}
}

static void check_valid_segment(uint16_t index, int ldt,
				uint32_t expected_ar, uint32_t expected_limit,
				bool verbose)
{
	uint32_t has_limit = 0, has_ar = 0, limit, ar;
	uint32_t selector = (index << 3) | (ldt << 2) | 3;

	asm ("lsl %[selector], %[limit]\n\t"
	     "jnz 1f\n\t"
	     "movl $1, %[has_limit]\n\t"
	     "1:"
	     : [limit] "=r" (limit), [has_limit] "+rm" (has_limit)
	     : [selector] "r" (selector));
	asm ("larl %[selector], %[ar]\n\t"
	     "jnz 1f\n\t"
	     "movl $1, %[has_ar]\n\t"
	     "1:"
	     : [ar] "=r" (ar), [has_ar] "+rm" (has_ar)
	     : [selector] "r" (selector));

	if (!has_limit || !has_ar) {
		printf("[FAIL]\t%s entry %hu is invalid but should be valid\n",
		       (ldt ? "LDT" : "GDT"), index);
		nerrs++;
		return;
	}

	if (ar != expected_ar) {
		printf("[FAIL]\t%s entry %hu has AR 0x%08X but expected 0x%08X\n",
		       (ldt ? "LDT" : "GDT"), index, ar, expected_ar);
		nerrs++;
	} else if (limit != expected_limit) {
		printf("[FAIL]\t%s entry %hu has limit 0x%08X but expected 0x%08X\n",
		       (ldt ? "LDT" : "GDT"), index, limit, expected_limit);
		nerrs++;
	} else if (verbose) {
		printf("[OK]\t%s entry %hu has AR 0x%08X and limit 0x%08X\n",
		       (ldt ? "LDT" : "GDT"), index, ar, limit);
	}
}

static bool install_valid_mode(const struct user_desc *desc, uint32_t ar,
			       bool oldmode)
{
	int ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11,
			  desc, sizeof(*desc));
	if (ret < -1)
		errno = -ret;
	if (ret == 0) {
		uint32_t limit = desc->limit;
		if (desc->limit_in_pages)
			limit = (limit << 12) + 4095;
		check_valid_segment(desc->entry_number, 1, ar, limit, true);
		return true;
	} else if (errno == ENOSYS) {
		printf("[OK]\tmodify_ldt returned -ENOSYS\n");
		return false;
	} else {
		if (desc->seg_32bit) {
			printf("[FAIL]\tUnexpected modify_ldt failure %d\n",
			       errno);
			nerrs++;
			return false;
		} else {
			printf("[OK]\tmodify_ldt rejected 16 bit segment\n");
			return false;
		}
	}
}

static bool install_valid(const struct user_desc *desc, uint32_t ar)
{
	return install_valid_mode(desc, ar, false);
}

static void install_invalid(const struct user_desc *desc, bool oldmode)
{
	int ret = syscall(SYS_modify_ldt, oldmode ? 1 : 0x11,
			  desc, sizeof(*desc));
	if (ret < -1)
		errno = -ret;
	if (ret == 0) {
		check_invalid_segment(desc->entry_number, 1);
	} else if (errno == ENOSYS) {
		printf("[OK]\tmodify_ldt returned -ENOSYS\n");
	} else {
		if (desc->seg_32bit) {
			printf("[FAIL]\tUnexpected modify_ldt failure %d\n",
			       errno);
			nerrs++;
		} else {
			printf("[OK]\tmodify_ldt rejected 16 bit segment\n");
		}
	}
}

static int safe_modify_ldt(int func, struct user_desc *ptr,
			   unsigned long bytecount)
{
	int ret = syscall(SYS_modify_ldt, 0x11, ptr, bytecount);
	if (ret < -1)
		errno = -ret;
	return ret;
}

static void fail_install(struct user_desc *desc)
{
	if (safe_modify_ldt(0x11, desc, sizeof(*desc)) == 0) {
		printf("[FAIL]\tmodify_ldt accepted a bad descriptor\n");
		nerrs++;
	} else if (errno == ENOSYS) {
		printf("[OK]\tmodify_ldt returned -ENOSYS\n");
	} else {
		printf("[OK]\tmodify_ldt failure %d\n", errno);
	}
}

static void do_simple_tests(void)
{
	struct user_desc desc = {
		.entry_number    = 0,
		.base_addr       = 0,
		.limit           = 10,
		.seg_32bit       = 1,
		.contents        = 2, /* Code, not conforming */
		.read_exec_only  = 0,
		.limit_in_pages  = 0,
		.seg_not_present = 0,
		.useable         = 0
	};
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE | AR_S | AR_P | AR_DB);

	desc.limit_in_pages = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_P | AR_DB | AR_G);

	check_invalid_segment(1, 1);

	desc.entry_number = 2;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_P | AR_DB | AR_G);

	check_invalid_segment(1, 1);

	desc.base_addr = 0xf0000000;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_P | AR_DB | AR_G);

	desc.useable = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_P | AR_DB | AR_G | AR_AVL);

	desc.seg_not_present = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_DB | AR_G | AR_AVL);

	desc.seg_32bit = 0;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_G | AR_AVL);

	desc.seg_32bit = 1;
	desc.contents = 0;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA |
		      AR_S | AR_DB | AR_G | AR_AVL);

	desc.read_exec_only = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA |
		      AR_S | AR_DB | AR_G | AR_AVL);

	desc.contents = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA_EXPDOWN |
		      AR_S | AR_DB | AR_G | AR_AVL);

	desc.read_exec_only = 0;
	desc.limit_in_pages = 0;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA_EXPDOWN |
		      AR_S | AR_DB | AR_AVL);

	desc.contents = 3;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE_CONF |
		      AR_S | AR_DB | AR_AVL);

	desc.read_exec_only = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XOCODE_CONF |
		      AR_S | AR_DB | AR_AVL);

	desc.read_exec_only = 0;
	desc.contents = 2;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE |
		      AR_S | AR_DB | AR_AVL);

	desc.read_exec_only = 1;

#ifdef __x86_64__
	desc.lm = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_XOCODE |
		      AR_S | AR_DB | AR_AVL);
	desc.lm = 0;
#endif

	bool entry1_okay = install_valid(&desc, AR_DPL3 | AR_TYPE_XOCODE |
					 AR_S | AR_DB | AR_AVL);

	if (entry1_okay) {
		printf("[RUN]\tTest fork\n");
		pid_t child = fork();
		if (child == 0) {
			nerrs = 0;
			check_valid_segment(desc.entry_number, 1,
					    AR_DPL3 | AR_TYPE_XOCODE |
					    AR_S | AR_DB | AR_AVL, desc.limit,
					    true);
			check_invalid_segment(1, 1);
			exit(nerrs ? 1 : 0);
		} else {
			int status;
			if (waitpid(child, &status, 0) != child ||
			    !WIFEXITED(status)) {
				printf("[FAIL]\tChild died\n");
				nerrs++;
			} else if (WEXITSTATUS(status) != 0) {
				printf("[FAIL]\tChild failed\n");
				nerrs++;
			} else {
				printf("[OK]\tChild succeeded\n");
			}
		}

		printf("[RUN]\tTest size\n");
		int i;
		for (i = 0; i < 8192; i++) {
			desc.entry_number = i;
			desc.limit = i;
			if (safe_modify_ldt(0x11, &desc, sizeof(desc)) != 0) {
				printf("[FAIL]\tFailed to install entry %d\n", i);
				nerrs++;
				break;
			}
		}
		for (int j = 0; j < i; j++) {
			check_valid_segment(j, 1, AR_DPL3 | AR_TYPE_XOCODE |
					    AR_S | AR_DB | AR_AVL, j, false);
		}
		printf("[DONE]\tSize test\n");
	} else {
		printf("[SKIP]\tSkipping fork and size tests because we have no LDT\n");
	}

	/* Test entry_number too high. */
	desc.entry_number = 8192;
	fail_install(&desc);

	/* Test deletion and actions mistakeable for deletion. */
	memset(&desc, 0, sizeof(desc));
	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S | AR_P);

	desc.seg_not_present = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S);

	desc.seg_not_present = 0;
	desc.read_exec_only = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA | AR_S | AR_P);

	desc.read_exec_only = 0;
	desc.seg_not_present = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S);

	desc.read_exec_only = 1;
	desc.limit = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA | AR_S);

	desc.limit = 0;
	desc.base_addr = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RODATA | AR_S);

	desc.base_addr = 0;
	install_invalid(&desc, false);

	desc.seg_not_present = 0;
	desc.read_exec_only = 0;
	desc.seg_32bit = 1;
	install_valid(&desc, AR_DPL3 | AR_TYPE_RWDATA | AR_S | AR_P | AR_DB);
	install_invalid(&desc, true);
}

/*
 * 0: thread is idle
 * 1: thread armed
 * 2: thread should clear LDT entry 0
 * 3: thread should exit
 */
static volatile unsigned int ftx;

static void *threadproc(void *ctx)
{
	cpu_set_t cpuset;
	CPU_ZERO(&cpuset);
	CPU_SET(1, &cpuset);
	if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0)
		err(1, "sched_setaffinity to CPU 1");	/* should never fail */

	while (1) {
		syscall(SYS_futex, &ftx, FUTEX_WAIT, 0, NULL, NULL, 0);
		while (ftx != 2) {
			if (ftx >= 3)
				return NULL;
		}

		/* clear LDT entry 0 */
		const struct user_desc desc = {};
		if (syscall(SYS_modify_ldt, 1, &desc, sizeof(desc)) != 0)
			err(1, "modify_ldt");

		/* If ftx == 2, set it to zero.  If ftx == 100, quit. */
		unsigned int x = -2;
		asm volatile ("lock xaddl %[x], %[ftx]" :
			      [x] "+r" (x), [ftx] "+m" (ftx));
		if (x != 2)
			return NULL;
	}
}

static void sethandler(int sig, void (*handler)(int, siginfo_t *, void *),
		       int flags)
{
	struct sigaction sa;
	memset(&sa, 0, sizeof(sa));
	sa.sa_sigaction = handler;
	sa.sa_flags = SA_SIGINFO | flags;
	sigemptyset(&sa.sa_mask);
	if (sigaction(sig, &sa, 0))
		err(1, "sigaction");

}

static jmp_buf jmpbuf;

static void sigsegv(int sig, siginfo_t *info, void *ctx_void)
{
	siglongjmp(jmpbuf, 1);
}

static void do_multicpu_tests(void)
{
	cpu_set_t cpuset;
	pthread_t thread;
	int failures = 0, iters = 5, i;
	unsigned short orig_ss;

	CPU_ZERO(&cpuset);
	CPU_SET(1, &cpuset);
	if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
		printf("[SKIP]\tCannot set affinity to CPU 1\n");
		return;
	}

	CPU_ZERO(&cpuset);
	CPU_SET(0, &cpuset);
	if (sched_setaffinity(0, sizeof(cpuset), &cpuset) != 0) {
		printf("[SKIP]\tCannot set affinity to CPU 0\n");
		return;
	}

	sethandler(SIGSEGV, sigsegv, 0);
#ifdef __i386__
	/* True 32-bit kernels send SIGILL instead of SIGSEGV on IRET faults. */
	sethandler(SIGILL, sigsegv, 0);
#endif

	printf("[RUN]\tCross-CPU LDT invalidation\n");

	if (pthread_create(&thread, 0, threadproc, 0) != 0)
		err(1, "pthread_create");

	asm volatile ("mov %%ss, %0" : "=rm" (orig_ss));

	for (i = 0; i < 5; i++) {
		if (sigsetjmp(jmpbuf, 1) != 0)
			continue;

		/* Make sure the thread is ready after the last test. */
		while (ftx != 0)
			;

		struct user_desc desc = {
			.entry_number    = 0,
			.base_addr       = 0,
			.limit           = 0xfffff,
			.seg_32bit       = 1,
			.contents        = 0, /* Data */
			.read_exec_only  = 0,
			.limit_in_pages  = 1,
			.seg_not_present = 0,
			.useable         = 0
		};

		if (safe_modify_ldt(0x11, &desc, sizeof(desc)) != 0) {
			if (errno != ENOSYS)
				err(1, "modify_ldt");
			printf("[SKIP]\tmodify_ldt unavailable\n");
			break;
		}

		/* Arm the thread. */
		ftx = 1;
		syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);

		asm volatile ("mov %0, %%ss" : : "r" (0x7));

		/* Go! */
		ftx = 2;

		while (ftx != 0)
			;

		/*
		 * On success, modify_ldt will segfault us synchronously,
		 * and we'll escape via siglongjmp.
		 */

		failures++;
		asm volatile ("mov %0, %%ss" : : "rm" (orig_ss));
	};

	ftx = 100;  /* Kill the thread. */
	syscall(SYS_futex, &ftx, FUTEX_WAKE, 0, NULL, NULL, 0);

	if (pthread_join(thread, NULL) != 0)
		err(1, "pthread_join");

	if (failures) {
		printf("[FAIL]\t%d of %d iterations failed\n", failures, iters);
		nerrs++;
	} else {
		printf("[OK]\tAll %d iterations succeeded\n", iters);
	}
}

static int finish_exec_test(void)
{
	/*
	 * In a sensible world, this would be check_invalid_segment(0, 1);
	 * For better or for worse, though, the LDT is inherited across exec.
	 * We can probably change this safely, but for now we test it.
	 */
	check_valid_segment(0, 1,
			    AR_DPL3 | AR_TYPE_XRCODE | AR_S | AR_P | AR_DB,
			    42, true);

	return nerrs ? 1 : 0;
}

static void do_exec_test(void)
{
	printf("[RUN]\tTest exec\n");

	struct user_desc desc = {
		.entry_number    = 0,
		.base_addr       = 0,
		.limit           = 42,
		.seg_32bit       = 1,
		.contents        = 2, /* Code, not conforming */
		.read_exec_only  = 0,
		.limit_in_pages  = 0,
		.seg_not_present = 0,
		.useable         = 0
	};
	install_valid(&desc, AR_DPL3 | AR_TYPE_XRCODE | AR_S | AR_P | AR_DB);

	pid_t child = fork();
	if (child == 0) {
		execl("/proc/self/exe", "ldt_gdt_test_exec", NULL);
		printf("[FAIL]\tCould not exec self\n");
		exit(1);	/* exec failed */
	} else {
		int status;
		if (waitpid(child, &status, 0) != child ||
		    !WIFEXITED(status)) {
			printf("[FAIL]\tChild died\n");
			nerrs++;
		} else if (WEXITSTATUS(status) != 0) {
			printf("[FAIL]\tChild failed\n");
			nerrs++;
		} else {
			printf("[OK]\tChild succeeded\n");
		}
	}
}

int main(int argc, char **argv)
{
	if (argc == 1 && !strcmp(argv[0], "ldt_gdt_test_exec"))
		return finish_exec_test();

	do_simple_tests();

	do_multicpu_tests();

	do_exec_test();

	return nerrs ? 1 : 0;
}
