File Index
Files and directories
Sign in
FILE

test_shadow_stack.c

File preview with syntax highlighting.

linux-6.19.14/tools/testing/selftests/x86/test_shadow_stack.c C
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * This program test's basic kernel shadow stack support. It enables shadow
   4 * stack manual via the arch_prctl(), instead of relying on glibc. It's
   5 * Makefile doesn't compile with shadow stack support, so it doesn't rely on
   6 * any particular glibc. As a result it can't do any operations that require
   7 * special glibc shadow stack support (longjmp(), swapcontext(), etc). Just
   8 * stick to the basics and hope the compiler doesn't do anything strange.
   9 */
  10
  11#define _GNU_SOURCE
  12
  13#include <sys/syscall.h>
  14#include <asm/mman.h>
  15#include <sys/mman.h>
  16#include <sys/stat.h>
  17#include <sys/wait.h>
  18#include <stdio.h>
  19#include <stdlib.h>
  20#include <fcntl.h>
  21#include <unistd.h>
  22#include <string.h>
  23#include <errno.h>
  24#include <stdbool.h>
  25#include <x86intrin.h>
  26#include <asm/prctl.h>
  27#include <sys/prctl.h>
  28#include <stdint.h>
  29#include <signal.h>
  30#include <pthread.h>
  31#include <sys/ioctl.h>
  32#include <linux/userfaultfd.h>
  33#include <setjmp.h>
  34#include <sys/ptrace.h>
  35#include <sys/signal.h>
  36#include <linux/elf.h>
  37#include <linux/perf_event.h>
  38
  39/*
  40 * Define the ABI defines if needed, so people can run the tests
  41 * without building the headers.
  42 */
  43#ifndef __NR_map_shadow_stack
  44#define __NR_map_shadow_stack	453
  45
  46#define SHADOW_STACK_SET_TOKEN	(1ULL << 0)
  47
  48#define ARCH_SHSTK_ENABLE	0x5001
  49#define ARCH_SHSTK_DISABLE	0x5002
  50#define ARCH_SHSTK_LOCK		0x5003
  51#define ARCH_SHSTK_UNLOCK	0x5004
  52#define ARCH_SHSTK_STATUS	0x5005
  53
  54#define ARCH_SHSTK_SHSTK	(1ULL <<  0)
  55#define ARCH_SHSTK_WRSS		(1ULL <<  1)
  56
  57#define NT_X86_SHSTK	0x204
  58#endif
  59
  60#define SS_SIZE 0x200000
  61#define PAGE_SIZE 0x1000
  62
  63#if (__GNUC__ < 8) || (__GNUC__ == 8 && __GNUC_MINOR__ < 5)
  64int main(int argc, char *argv[])
  65{
  66	printf("[SKIP]\tCompiler does not support CET.\n");
  67	return 0;
  68}
  69#else
  70void write_shstk(unsigned long *addr, unsigned long val)
  71{
  72	asm volatile("wrssq %[val], (%[addr])\n"
  73		     : "=m" (addr)
  74		     : [addr] "r" (addr), [val] "r" (val));
  75}
  76
  77static inline unsigned long __attribute__((always_inline)) get_ssp(void)
  78{
  79	unsigned long ret = 0;
  80
  81	asm volatile("xor %0, %0; rdsspq %0" : "=r" (ret));
  82	return ret;
  83}
  84
  85/*
  86 * For use in inline enablement of shadow stack.
  87 *
  88 * The program can't return from the point where shadow stack gets enabled
  89 * because there will be no address on the shadow stack. So it can't use
  90 * syscall() for enablement, since it is a function.
  91 *
  92 * Based on code from nolibc.h. Keep a copy here because this can't pull in all
  93 * of nolibc.h.
  94 */
  95#define ARCH_PRCTL(arg1, arg2)					\
  96({								\
  97	long _ret;						\
  98	register long _num  asm("eax") = __NR_arch_prctl;	\
  99	register long _arg1 asm("rdi") = (long)(arg1);		\
 100	register long _arg2 asm("rsi") = (long)(arg2);		\
 101								\
 102	asm volatile (						\
 103		"syscall\n"					\
 104		: "=a"(_ret)					\
 105		: "r"(_arg1), "r"(_arg2),			\
 106		  "0"(_num)					\
 107		: "rcx", "r11", "memory", "cc"			\
 108	);							\
 109	_ret;							\
 110})
 111
 112void *create_shstk(void *addr)
 113{
 114	return (void *)syscall(__NR_map_shadow_stack, addr, SS_SIZE, SHADOW_STACK_SET_TOKEN);
 115}
 116
 117void *create_normal_mem(void *addr)
 118{
 119	return mmap(addr, SS_SIZE, PROT_READ | PROT_WRITE,
 120		    MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
 121}
 122
 123void free_shstk(void *shstk)
 124{
 125	munmap(shstk, SS_SIZE);
 126}
 127
 128int reset_shstk(void *shstk)
 129{
 130	return madvise(shstk, SS_SIZE, MADV_DONTNEED);
 131}
 132
 133void try_shstk(unsigned long new_ssp)
 134{
 135	unsigned long ssp;
 136
 137	printf("[INFO]\tnew_ssp = %lx, *new_ssp = %lx\n",
 138	       new_ssp, *((unsigned long *)new_ssp));
 139
 140	ssp = get_ssp();
 141	printf("[INFO]\tchanging ssp from %lx to %lx\n", ssp, new_ssp);
 142
 143	asm volatile("rstorssp (%0)\n":: "r" (new_ssp));
 144	asm volatile("saveprevssp");
 145	printf("[INFO]\tssp is now %lx\n", get_ssp());
 146
 147	/* Switch back to original shadow stack */
 148	ssp -= 8;
 149	asm volatile("rstorssp (%0)\n":: "r" (ssp));
 150	asm volatile("saveprevssp");
 151}
 152
 153int test_shstk_pivot(void)
 154{
 155	void *shstk = create_shstk(0);
 156
 157	if (shstk == MAP_FAILED) {
 158		printf("[FAIL]\tError creating shadow stack: %d\n", errno);
 159		return 1;
 160	}
 161	try_shstk((unsigned long)shstk + SS_SIZE - 8);
 162	free_shstk(shstk);
 163
 164	printf("[OK]\tShadow stack pivot\n");
 165	return 0;
 166}
 167
 168int test_shstk_faults(void)
 169{
 170	unsigned long *shstk = create_shstk(0);
 171
 172	/* Read shadow stack, test if it's zero to not get read optimized out */
 173	if (*shstk != 0)
 174		goto err;
 175
 176	/* Wrss memory that was already read. */
 177	write_shstk(shstk, 1);
 178	if (*shstk != 1)
 179		goto err;
 180
 181	/* Page out memory, so we can wrss it again. */
 182	if (reset_shstk((void *)shstk))
 183		goto err;
 184
 185	write_shstk(shstk, 1);
 186	if (*shstk != 1)
 187		goto err;
 188
 189	printf("[OK]\tShadow stack faults\n");
 190	return 0;
 191
 192err:
 193	return 1;
 194}
 195
 196unsigned long saved_ssp;
 197unsigned long saved_ssp_val;
 198volatile bool segv_triggered;
 199
 200void __attribute__((noinline)) violate_ss(void)
 201{
 202	saved_ssp = get_ssp();
 203	saved_ssp_val = *(unsigned long *)saved_ssp;
 204
 205	/* Corrupt shadow stack */
 206	printf("[INFO]\tCorrupting shadow stack\n");
 207	write_shstk((void *)saved_ssp, 0);
 208}
 209
 210void segv_handler(int signum, siginfo_t *si, void *uc)
 211{
 212	printf("[INFO]\tGenerated shadow stack violation successfully\n");
 213
 214	segv_triggered = true;
 215
 216	/* Fix shadow stack */
 217	write_shstk((void *)saved_ssp, saved_ssp_val);
 218}
 219
 220int test_shstk_violation(void)
 221{
 222	struct sigaction sa = {};
 223
 224	sa.sa_sigaction = segv_handler;
 225	sa.sa_flags = SA_SIGINFO;
 226	if (sigaction(SIGSEGV, &sa, NULL))
 227		return 1;
 228
 229	segv_triggered = false;
 230
 231	/* Make sure segv_triggered is set before violate_ss() */
 232	asm volatile("" : : : "memory");
 233
 234	violate_ss();
 235
 236	signal(SIGSEGV, SIG_DFL);
 237
 238	printf("[OK]\tShadow stack violation test\n");
 239
 240	return !segv_triggered;
 241}
 242
 243/* Gup test state */
 244#define MAGIC_VAL 0x12345678
 245bool is_shstk_access;
 246void *shstk_ptr;
 247int fd;
 248
 249void reset_test_shstk(void *addr)
 250{
 251	if (shstk_ptr)
 252		free_shstk(shstk_ptr);
 253	shstk_ptr = create_shstk(addr);
 254}
 255
 256void test_access_fix_handler(int signum, siginfo_t *si, void *uc)
 257{
 258	printf("[INFO]\tViolation from %s\n", is_shstk_access ? "shstk access" : "normal write");
 259
 260	segv_triggered = true;
 261
 262	/* Fix shadow stack */
 263	if (is_shstk_access) {
 264		reset_test_shstk(shstk_ptr);
 265		return;
 266	}
 267
 268	free_shstk(shstk_ptr);
 269	create_normal_mem(shstk_ptr);
 270}
 271
 272bool test_shstk_access(void *ptr)
 273{
 274	is_shstk_access = true;
 275	segv_triggered = false;
 276	write_shstk(ptr, MAGIC_VAL);
 277
 278	asm volatile("" : : : "memory");
 279
 280	return segv_triggered;
 281}
 282
 283bool test_write_access(void *ptr)
 284{
 285	is_shstk_access = false;
 286	segv_triggered = false;
 287	*(unsigned long *)ptr = MAGIC_VAL;
 288
 289	asm volatile("" : : : "memory");
 290
 291	return segv_triggered;
 292}
 293
 294bool gup_write(void *ptr)
 295{
 296	unsigned long val;
 297
 298	lseek(fd, (unsigned long)ptr, SEEK_SET);
 299	if (write(fd, &val, sizeof(val)) < 0)
 300		return 1;
 301
 302	return 0;
 303}
 304
 305bool gup_read(void *ptr)
 306{
 307	unsigned long val;
 308
 309	lseek(fd, (unsigned long)ptr, SEEK_SET);
 310	if (read(fd, &val, sizeof(val)) < 0)
 311		return 1;
 312
 313	return 0;
 314}
 315
 316int test_gup(void)
 317{
 318	struct sigaction sa = {};
 319	int status;
 320	pid_t pid;
 321
 322	sa.sa_sigaction = test_access_fix_handler;
 323	sa.sa_flags = SA_SIGINFO;
 324	if (sigaction(SIGSEGV, &sa, NULL))
 325		return 1;
 326
 327	segv_triggered = false;
 328
 329	fd = open("/proc/self/mem", O_RDWR);
 330	if (fd == -1)
 331		return 1;
 332
 333	reset_test_shstk(0);
 334	if (gup_read(shstk_ptr))
 335		return 1;
 336	if (test_shstk_access(shstk_ptr))
 337		return 1;
 338	printf("[INFO]\tGup read -> shstk access success\n");
 339
 340	reset_test_shstk(0);
 341	if (gup_write(shstk_ptr))
 342		return 1;
 343	if (test_shstk_access(shstk_ptr))
 344		return 1;
 345	printf("[INFO]\tGup write -> shstk access success\n");
 346
 347	reset_test_shstk(0);
 348	if (gup_read(shstk_ptr))
 349		return 1;
 350	if (!test_write_access(shstk_ptr))
 351		return 1;
 352	printf("[INFO]\tGup read -> write access success\n");
 353
 354	reset_test_shstk(0);
 355	if (gup_write(shstk_ptr))
 356		return 1;
 357	if (!test_write_access(shstk_ptr))
 358		return 1;
 359	printf("[INFO]\tGup write -> write access success\n");
 360
 361	close(fd);
 362
 363	/* COW/gup test */
 364	reset_test_shstk(0);
 365	pid = fork();
 366	if (!pid) {
 367		fd = open("/proc/self/mem", O_RDWR);
 368		if (fd == -1)
 369			exit(1);
 370
 371		if (gup_write(shstk_ptr)) {
 372			close(fd);
 373			exit(1);
 374		}
 375		close(fd);
 376		exit(0);
 377	}
 378	waitpid(pid, &status, 0);
 379	if (WEXITSTATUS(status)) {
 380		printf("[FAIL]\tWrite in child failed\n");
 381		return 1;
 382	}
 383	if (*(unsigned long *)shstk_ptr == MAGIC_VAL) {
 384		printf("[FAIL]\tWrite in child wrote through to shared memory\n");
 385		return 1;
 386	}
 387
 388	printf("[INFO]\tCow gup write -> write access success\n");
 389
 390	free_shstk(shstk_ptr);
 391
 392	signal(SIGSEGV, SIG_DFL);
 393
 394	printf("[OK]\tShadow gup test\n");
 395
 396	return 0;
 397}
 398
 399int test_mprotect(void)
 400{
 401	struct sigaction sa = {};
 402
 403	sa.sa_sigaction = test_access_fix_handler;
 404	sa.sa_flags = SA_SIGINFO;
 405	if (sigaction(SIGSEGV, &sa, NULL))
 406		return 1;
 407
 408	segv_triggered = false;
 409
 410	/* mprotect a shadow stack as read only */
 411	reset_test_shstk(0);
 412	if (mprotect(shstk_ptr, SS_SIZE, PROT_READ) < 0) {
 413		printf("[FAIL]\tmprotect(PROT_READ) failed\n");
 414		return 1;
 415	}
 416
 417	/* try to wrss it and fail */
 418	if (!test_shstk_access(shstk_ptr)) {
 419		printf("[FAIL]\tShadow stack access to read-only memory succeeded\n");
 420		return 1;
 421	}
 422
 423	/*
 424	 * The shadow stack was reset above to resolve the fault, make the new one
 425	 * read-only.
 426	 */
 427	if (mprotect(shstk_ptr, SS_SIZE, PROT_READ) < 0) {
 428		printf("[FAIL]\tmprotect(PROT_READ) failed\n");
 429		return 1;
 430	}
 431
 432	/* then back to writable */
 433	if (mprotect(shstk_ptr, SS_SIZE, PROT_WRITE | PROT_READ) < 0) {
 434		printf("[FAIL]\tmprotect(PROT_WRITE) failed\n");
 435		return 1;
 436	}
 437
 438	/* then wrss to it and succeed */
 439	if (test_shstk_access(shstk_ptr)) {
 440		printf("[FAIL]\tShadow stack access to mprotect() writable memory failed\n");
 441		return 1;
 442	}
 443
 444	free_shstk(shstk_ptr);
 445
 446	signal(SIGSEGV, SIG_DFL);
 447
 448	printf("[OK]\tmprotect() test\n");
 449
 450	return 0;
 451}
 452
 453char zero[4096];
 454
 455static void *uffd_thread(void *arg)
 456{
 457	struct uffdio_copy req;
 458	int uffd = *(int *)arg;
 459	struct uffd_msg msg;
 460	int ret;
 461
 462	while (1) {
 463		ret = read(uffd, &msg, sizeof(msg));
 464		if (ret > 0)
 465			break;
 466		else if (errno == EAGAIN)
 467			continue;
 468		return (void *)1;
 469	}
 470
 471	req.dst = msg.arg.pagefault.address;
 472	req.src = (__u64)zero;
 473	req.len = 4096;
 474	req.mode = 0;
 475
 476	if (ioctl(uffd, UFFDIO_COPY, &req))
 477		return (void *)1;
 478
 479	return (void *)0;
 480}
 481
 482int test_userfaultfd(void)
 483{
 484	struct uffdio_register uffdio_register;
 485	struct uffdio_api uffdio_api;
 486	struct sigaction sa = {};
 487	pthread_t thread;
 488	void *res;
 489	int uffd;
 490
 491	sa.sa_sigaction = test_access_fix_handler;
 492	sa.sa_flags = SA_SIGINFO;
 493	if (sigaction(SIGSEGV, &sa, NULL))
 494		return 1;
 495
 496	uffd = syscall(__NR_userfaultfd, O_CLOEXEC | O_NONBLOCK);
 497	if (uffd < 0) {
 498		printf("[SKIP]\tUserfaultfd unavailable.\n");
 499		return 0;
 500	}
 501
 502	reset_test_shstk(0);
 503
 504	uffdio_api.api = UFFD_API;
 505	uffdio_api.features = 0;
 506	if (ioctl(uffd, UFFDIO_API, &uffdio_api))
 507		goto err;
 508
 509	uffdio_register.range.start = (__u64)shstk_ptr;
 510	uffdio_register.range.len = 4096;
 511	uffdio_register.mode = UFFDIO_REGISTER_MODE_MISSING;
 512	if (ioctl(uffd, UFFDIO_REGISTER, &uffdio_register))
 513		goto err;
 514
 515	if (pthread_create(&thread, NULL, &uffd_thread, &uffd))
 516		goto err;
 517
 518	reset_shstk(shstk_ptr);
 519	test_shstk_access(shstk_ptr);
 520
 521	if (pthread_join(thread, &res))
 522		goto err;
 523
 524	if (test_shstk_access(shstk_ptr))
 525		goto err;
 526
 527	free_shstk(shstk_ptr);
 528
 529	signal(SIGSEGV, SIG_DFL);
 530
 531	if (!res)
 532		printf("[OK]\tUserfaultfd test\n");
 533	return !!res;
 534err:
 535	free_shstk(shstk_ptr);
 536	close(uffd);
 537	signal(SIGSEGV, SIG_DFL);
 538	return 1;
 539}
 540
 541/* Simple linked list for keeping track of mappings in test_guard_gap() */
 542struct node {
 543	struct node *next;
 544	void *mapping;
 545};
 546
 547/*
 548 * This tests whether mmap will place other mappings in a shadow stack's guard
 549 * gap. The steps are:
 550 *   1. Finds an empty place by mapping and unmapping something.
 551 *   2. Map a shadow stack in the middle of the known empty area.
 552 *   3. Map a bunch of PAGE_SIZE mappings. These will use the search down
 553 *      direction, filling any gaps until it encounters the shadow stack's
 554 *      guard gap.
 555 *   4. When a mapping lands below the shadow stack from step 2, then all
 556 *      of the above gaps are filled. The search down algorithm will have
 557 *      looked at the shadow stack gaps.
 558 *   5. See if it landed in the gap.
 559 */
 560int test_guard_gap_other_gaps(void)
 561{
 562	void *free_area, *shstk, *test_map = (void *)0xFFFFFFFFFFFFFFFF;
 563	struct node *head = NULL, *cur;
 564
 565	free_area = mmap(0, SS_SIZE * 3, PROT_READ | PROT_WRITE,
 566			 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 567	munmap(free_area, SS_SIZE * 3);
 568
 569	shstk = create_shstk(free_area + SS_SIZE);
 570	if (shstk == MAP_FAILED)
 571		return 1;
 572
 573	while (test_map > shstk) {
 574		test_map = mmap(0, PAGE_SIZE, PROT_READ | PROT_WRITE,
 575				MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 576		if (test_map == MAP_FAILED)
 577			return 1;
 578		cur = malloc(sizeof(*cur));
 579		cur->mapping = test_map;
 580
 581		cur->next = head;
 582		head = cur;
 583	}
 584
 585	while (head) {
 586		cur = head;
 587		head = cur->next;
 588		munmap(cur->mapping, PAGE_SIZE);
 589		free(cur);
 590	}
 591
 592	free_shstk(shstk);
 593
 594	if (shstk - test_map - PAGE_SIZE != PAGE_SIZE)
 595		return 1;
 596
 597	printf("[OK]\tGuard gap test, other mapping's gaps\n");
 598
 599	return 0;
 600}
 601
 602/* Tests respecting the guard gap of the mapping getting placed */
 603int test_guard_gap_new_mappings_gaps(void)
 604{
 605	void *free_area, *shstk_start, *test_map = (void *)0xFFFFFFFFFFFFFFFF;
 606	struct node *head = NULL, *cur;
 607	int ret = 0;
 608
 609	free_area = mmap(0, PAGE_SIZE * 4, PROT_READ | PROT_WRITE,
 610			 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 611	munmap(free_area, PAGE_SIZE * 4);
 612
 613	/* Test letting map_shadow_stack find a free space */
 614	shstk_start = mmap(free_area, PAGE_SIZE, PROT_READ | PROT_WRITE,
 615			   MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
 616	if (shstk_start == MAP_FAILED || shstk_start != free_area)
 617		return 1;
 618
 619	while (test_map > shstk_start) {
 620		test_map = (void *)syscall(__NR_map_shadow_stack, 0, PAGE_SIZE, 0);
 621		if (test_map == MAP_FAILED) {
 622			printf("[INFO]\tmap_shadow_stack MAP_FAILED\n");
 623			ret = 1;
 624			break;
 625		}
 626
 627		cur = malloc(sizeof(*cur));
 628		cur->mapping = test_map;
 629
 630		cur->next = head;
 631		head = cur;
 632
 633		if (test_map == free_area + PAGE_SIZE) {
 634			printf("[INFO]\tNew mapping has other mapping in guard gap!\n");
 635			ret = 1;
 636			break;
 637		}
 638	}
 639
 640	while (head) {
 641		cur = head;
 642		head = cur->next;
 643		munmap(cur->mapping, PAGE_SIZE);
 644		free(cur);
 645	}
 646
 647	munmap(shstk_start, PAGE_SIZE);
 648
 649	if (!ret)
 650		printf("[OK]\tGuard gap test, placement mapping's gaps\n");
 651
 652	return ret;
 653}
 654
 655/*
 656 * Too complicated to pull it out of the 32 bit header, but also get the
 657 * 64 bit one needed above. Just define a copy here.
 658 */
 659#define __NR_compat_sigaction 67
 660
 661/*
 662 * Call 32 bit signal handler to get 32 bit signals ABI. Make sure
 663 * to push the registers that will get clobbered.
 664 */
 665int sigaction32(int signum, const struct sigaction *restrict act,
 666		struct sigaction *restrict oldact)
 667{
 668	register long syscall_reg asm("eax") = __NR_compat_sigaction;
 669	register long signum_reg asm("ebx") = signum;
 670	register long act_reg asm("ecx") = (long)act;
 671	register long oldact_reg asm("edx") = (long)oldact;
 672	int ret = 0;
 673
 674	asm volatile ("int $0x80;"
 675		      : "=a"(ret), "=m"(oldact)
 676		      : "r"(syscall_reg), "r"(signum_reg), "r"(act_reg),
 677			"r"(oldact_reg)
 678		      : "r8", "r9", "r10", "r11"
 679		     );
 680
 681	return ret;
 682}
 683
 684sigjmp_buf jmp_buffer;
 685
 686void segv_gp_handler(int signum, siginfo_t *si, void *uc)
 687{
 688	segv_triggered = true;
 689
 690	/*
 691	 * To work with old glibc, this can't rely on siglongjmp working with
 692	 * shadow stack enabled, so disable shadow stack before siglongjmp().
 693	 */
 694	ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK);
 695	siglongjmp(jmp_buffer, -1);
 696}
 697
 698/*
 699 * Transition to 32 bit mode and check that a #GP triggers a segfault.
 700 */
 701int test_32bit(void)
 702{
 703	struct sigaction sa = {};
 704	struct sigaction *sa32;
 705
 706	/* Create sigaction in 32 bit address range */
 707	sa32 = mmap(0, 4096, PROT_READ | PROT_WRITE,
 708		    MAP_32BIT | MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
 709	sa32->sa_flags = SA_SIGINFO;
 710
 711	sa.sa_sigaction = segv_gp_handler;
 712	sa.sa_flags = SA_SIGINFO;
 713	if (sigaction(SIGSEGV, &sa, NULL))
 714		return 1;
 715
 716
 717	segv_triggered = false;
 718
 719	/* Make sure segv_triggered is set before triggering the #GP */
 720	asm volatile("" : : : "memory");
 721
 722	/*
 723	 * Set handler to somewhere in 32 bit address space
 724	 */
 725	sa32->sa_handler = (void *)sa32;
 726	if (sigaction32(SIGUSR1, sa32, NULL))
 727		return 1;
 728
 729	if (!sigsetjmp(jmp_buffer, 1))
 730		raise(SIGUSR1);
 731
 732	if (segv_triggered)
 733		printf("[OK]\t32 bit test\n");
 734
 735	return !segv_triggered;
 736}
 737
 738static int parse_uint_from_file(const char *file, const char *fmt)
 739{
 740	int err, ret;
 741	FILE *f;
 742
 743	f = fopen(file, "re");
 744	if (!f) {
 745		err = -errno;
 746		printf("failed to open '%s': %d\n", file, err);
 747		return err;
 748	}
 749	err = fscanf(f, fmt, &ret);
 750	if (err != 1) {
 751		err = err == EOF ? -EIO : -errno;
 752		printf("failed to parse '%s': %d\n", file, err);
 753		fclose(f);
 754		return err;
 755	}
 756	fclose(f);
 757	return ret;
 758}
 759
 760static int determine_uprobe_perf_type(void)
 761{
 762	const char *file = "/sys/bus/event_source/devices/uprobe/type";
 763
 764	return parse_uint_from_file(file, "%d\n");
 765}
 766
 767static int determine_uprobe_retprobe_bit(void)
 768{
 769	const char *file = "/sys/bus/event_source/devices/uprobe/format/retprobe";
 770
 771	return parse_uint_from_file(file, "config:%d\n");
 772}
 773
 774static ssize_t get_uprobe_offset(const void *addr)
 775{
 776	size_t start, end, base;
 777	char buf[256];
 778	bool found = false;
 779	FILE *f;
 780
 781	f = fopen("/proc/self/maps", "r");
 782	if (!f)
 783		return -errno;
 784
 785	while (fscanf(f, "%zx-%zx %s %zx %*[^\n]\n", &start, &end, buf, &base) == 4) {
 786		if (buf[2] == 'x' && (uintptr_t)addr >= start && (uintptr_t)addr < end) {
 787			found = true;
 788			break;
 789		}
 790	}
 791
 792	fclose(f);
 793
 794	if (!found)
 795		return -ESRCH;
 796
 797	return (uintptr_t)addr - start + base;
 798}
 799
 800static __attribute__((noinline)) void uretprobe_trigger(void)
 801{
 802	asm volatile ("");
 803}
 804
 805/*
 806 * This test setups return uprobe, which is sensitive to shadow stack
 807 * (crashes without extra fix). After executing the uretprobe we fail
 808 * the test if we receive SIGSEGV, no crash means we're good.
 809 *
 810 * Helper functions above borrowed from bpf selftests.
 811 */
 812static int test_uretprobe(void)
 813{
 814	const size_t attr_sz = sizeof(struct perf_event_attr);
 815	const char *file = "/proc/self/exe";
 816	int bit, fd = 0, type, err = 1;
 817	struct perf_event_attr attr;
 818	struct sigaction sa = {};
 819	ssize_t offset;
 820
 821	type = determine_uprobe_perf_type();
 822	if (type < 0) {
 823		if (type == -ENOENT)
 824			printf("[SKIP]\tUretprobe test, uprobes are not available\n");
 825		return 0;
 826	}
 827
 828	offset = get_uprobe_offset(uretprobe_trigger);
 829	if (offset < 0)
 830		return 1;
 831
 832	bit = determine_uprobe_retprobe_bit();
 833	if (bit < 0)
 834		return 1;
 835
 836	sa.sa_sigaction = segv_gp_handler;
 837	sa.sa_flags = SA_SIGINFO;
 838	if (sigaction(SIGSEGV, &sa, NULL))
 839		return 1;
 840
 841	/* Setup return uprobe through perf event interface. */
 842	memset(&attr, 0, attr_sz);
 843	attr.size = attr_sz;
 844	attr.type = type;
 845	attr.config = 1 << bit;
 846	attr.config1 = (__u64) (unsigned long) file;
 847	attr.config2 = offset;
 848
 849	fd = syscall(__NR_perf_event_open, &attr, 0 /* pid */, -1 /* cpu */,
 850		     -1 /* group_fd */, PERF_FLAG_FD_CLOEXEC);
 851	if (fd < 0)
 852		goto out;
 853
 854	if (sigsetjmp(jmp_buffer, 1))
 855		goto out;
 856
 857	ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK);
 858
 859	/*
 860	 * This either segfaults and goes through sigsetjmp above
 861	 * or succeeds and we're good.
 862	 */
 863	uretprobe_trigger();
 864
 865	printf("[OK]\tUretprobe test\n");
 866	err = 0;
 867
 868out:
 869	ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK);
 870	signal(SIGSEGV, SIG_DFL);
 871	if (fd)
 872		close(fd);
 873	return err;
 874}
 875
 876void segv_handler_ptrace(int signum, siginfo_t *si, void *uc)
 877{
 878	/* The SSP adjustment caused a segfault. */
 879	exit(0);
 880}
 881
 882int test_ptrace(void)
 883{
 884	unsigned long saved_ssp, ssp = 0;
 885	struct sigaction sa= {};
 886	struct iovec iov;
 887	int status;
 888	int pid;
 889
 890	iov.iov_base = &ssp;
 891	iov.iov_len = sizeof(ssp);
 892
 893	pid = fork();
 894	if (!pid) {
 895		ssp = get_ssp();
 896
 897		sa.sa_sigaction = segv_handler_ptrace;
 898		sa.sa_flags = SA_SIGINFO;
 899		if (sigaction(SIGSEGV, &sa, NULL))
 900			return 1;
 901
 902		ptrace(PTRACE_TRACEME, NULL, NULL, NULL);
 903		/*
 904		 * The parent will tweak the SSP and return from this function
 905		 * will #CP.
 906		 */
 907		raise(SIGTRAP);
 908
 909		exit(1);
 910	}
 911
 912	while (waitpid(pid, &status, 0) != -1 && WSTOPSIG(status) != SIGTRAP);
 913
 914	if (ptrace(PTRACE_GETREGSET, pid, NT_X86_SHSTK, &iov)) {
 915		printf("[INFO]\tFailed to PTRACE_GETREGS\n");
 916		goto out_kill;
 917	}
 918
 919	if (!ssp) {
 920		printf("[INFO]\tPtrace child SSP was 0\n");
 921		goto out_kill;
 922	}
 923
 924	saved_ssp = ssp;
 925
 926	iov.iov_len = 0;
 927	if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
 928		printf("[INFO]\tToo small size accepted via PTRACE_SETREGS\n");
 929		goto out_kill;
 930	}
 931
 932	iov.iov_len = sizeof(ssp) + 1;
 933	if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
 934		printf("[INFO]\tToo large size accepted via PTRACE_SETREGS\n");
 935		goto out_kill;
 936	}
 937
 938	ssp += 1;
 939	if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
 940		printf("[INFO]\tUnaligned SSP written via PTRACE_SETREGS\n");
 941		goto out_kill;
 942	}
 943
 944	ssp = 0xFFFFFFFFFFFF0000;
 945	if (!ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
 946		printf("[INFO]\tKernel range SSP written via PTRACE_SETREGS\n");
 947		goto out_kill;
 948	}
 949
 950	/*
 951	 * Tweak the SSP so the child with #CP when it resumes and returns
 952	 * from raise()
 953	 */
 954	ssp = saved_ssp + 8;
 955	iov.iov_len = sizeof(ssp);
 956	if (ptrace(PTRACE_SETREGSET, pid, NT_X86_SHSTK, &iov)) {
 957		printf("[INFO]\tFailed to PTRACE_SETREGS\n");
 958		goto out_kill;
 959	}
 960
 961	if (ptrace(PTRACE_DETACH, pid, NULL, NULL)) {
 962		printf("[INFO]\tFailed to PTRACE_DETACH\n");
 963		goto out_kill;
 964	}
 965
 966	waitpid(pid, &status, 0);
 967	if (WEXITSTATUS(status))
 968		return 1;
 969
 970	printf("[OK]\tPtrace test\n");
 971	return 0;
 972
 973out_kill:
 974	kill(pid, SIGKILL);
 975	return 1;
 976}
 977
 978int main(int argc, char *argv[])
 979{
 980	int ret = 0;
 981
 982	if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK)) {
 983		printf("[SKIP]\tCould not enable Shadow stack\n");
 984		return 1;
 985	}
 986
 987	if (ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK)) {
 988		ret = 1;
 989		printf("[FAIL]\tDisabling shadow stack failed\n");
 990	}
 991
 992	if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_SHSTK)) {
 993		printf("[SKIP]\tCould not re-enable Shadow stack\n");
 994		return 1;
 995	}
 996
 997	if (ARCH_PRCTL(ARCH_SHSTK_ENABLE, ARCH_SHSTK_WRSS)) {
 998		printf("[SKIP]\tCould not enable WRSS\n");
 999		ret = 1;
1000		goto out;
1001	}
1002
1003	/* Should have succeeded if here, but this is a test, so double check. */
1004	if (!get_ssp()) {
1005		printf("[FAIL]\tShadow stack disabled\n");
1006		return 1;
1007	}
1008
1009	if (test_shstk_pivot()) {
1010		ret = 1;
1011		printf("[FAIL]\tShadow stack pivot\n");
1012		goto out;
1013	}
1014
1015	if (test_shstk_faults()) {
1016		ret = 1;
1017		printf("[FAIL]\tShadow stack fault test\n");
1018		goto out;
1019	}
1020
1021	if (test_shstk_violation()) {
1022		ret = 1;
1023		printf("[FAIL]\tShadow stack violation test\n");
1024		goto out;
1025	}
1026
1027	if (test_gup()) {
1028		ret = 1;
1029		printf("[FAIL]\tShadow shadow stack gup\n");
1030		goto out;
1031	}
1032
1033	if (test_mprotect()) {
1034		ret = 1;
1035		printf("[FAIL]\tShadow shadow mprotect test\n");
1036		goto out;
1037	}
1038
1039	if (test_userfaultfd()) {
1040		ret = 1;
1041		printf("[FAIL]\tUserfaultfd test\n");
1042		goto out;
1043	}
1044
1045	if (test_guard_gap_other_gaps()) {
1046		ret = 1;
1047		printf("[FAIL]\tGuard gap test, other mappings' gaps\n");
1048		goto out;
1049	}
1050
1051	if (test_guard_gap_new_mappings_gaps()) {
1052		ret = 1;
1053		printf("[FAIL]\tGuard gap test, placement mapping's gaps\n");
1054		goto out;
1055	}
1056
1057	if (test_ptrace()) {
1058		ret = 1;
1059		printf("[FAIL]\tptrace test\n");
1060	}
1061
1062	if (test_32bit()) {
1063		ret = 1;
1064		printf("[FAIL]\t32 bit test\n");
1065		goto out;
1066	}
1067
1068	if (test_uretprobe()) {
1069		ret = 1;
1070		printf("[FAIL]\turetprobe test\n");
1071		goto out;
1072	}
1073
1074	return ret;
1075
1076out:
1077	/*
1078	 * Disable shadow stack before the function returns, or there will be a
1079	 * shadow stack violation.
1080	 */
1081	if (ARCH_PRCTL(ARCH_SHSTK_DISABLE, ARCH_SHSTK_SHSTK)) {
1082		ret = 1;
1083		printf("[FAIL]\tDisabling shadow stack failed\n");
1084	}
1085
1086	return ret;
1087}
1088#endif
~/ Read-only file preview.