test_shadow_stack.c 23 KB

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