1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Test that we can't sigreturn to kernel addresses, or to kernel mode. 4 */ 5 6 #define _GNU_SOURCE 7 8 #include <stdio.h> 9 #include <signal.h> 10 #include <stdlib.h> 11 #include <sys/types.h> 12 #include <sys/wait.h> 13 #include <unistd.h> 14 15 #include "utils.h" 16 17 #define MSR_PR (1ul << 14) 18 19 static volatile unsigned long long sigreturn_addr; 20 static volatile unsigned long long sigreturn_msr_mask; 21 22 static void sigusr1_handler(int signo, siginfo_t *si, void *uc_ptr) 23 { 24 ucontext_t *uc = (ucontext_t *)uc_ptr; 25 26 if (sigreturn_addr) 27 UCONTEXT_NIA(uc) = sigreturn_addr; 28 29 if (sigreturn_msr_mask) 30 UCONTEXT_MSR(uc) &= sigreturn_msr_mask; 31 } 32 33 static pid_t fork_child(void) 34 { 35 pid_t pid; 36 37 pid = fork(); 38 if (pid == 0) { 39 raise(SIGUSR1); 40 exit(0); 41 } 42 43 return pid; 44 } 45 46 static int expect_segv(pid_t pid) 47 { 48 int child_ret; 49 50 waitpid(pid, &child_ret, 0); 51 FAIL_IF(WIFEXITED(child_ret)); 52 FAIL_IF(!WIFSIGNALED(child_ret)); 53 FAIL_IF(WTERMSIG(child_ret) != 11); 54 55 return 0; 56 } 57 58 int test_sigreturn_kernel(void) 59 { 60 struct sigaction act; 61 int child_ret, i; 62 pid_t pid; 63 64 act.sa_sigaction = sigusr1_handler; 65 act.sa_flags = SA_SIGINFO; 66 sigemptyset(&act.sa_mask); 67 68 FAIL_IF(sigaction(SIGUSR1, &act, NULL)); 69 70 for (i = 0; i < 2; i++) { 71 // Return to kernel 72 sigreturn_addr = 0xcull << 60; 73 pid = fork_child(); 74 expect_segv(pid); 75 76 // Return to kernel virtual 77 sigreturn_addr = 0xc008ull << 48; 78 pid = fork_child(); 79 expect_segv(pid); 80 81 // Return out of range 82 sigreturn_addr = 0xc010ull << 48; 83 pid = fork_child(); 84 expect_segv(pid); 85 86 // Return to no-man's land, just below PAGE_OFFSET 87 sigreturn_addr = (0xcull << 60) - (64 * 1024); 88 pid = fork_child(); 89 expect_segv(pid); 90 91 // Return to no-man's land, above TASK_SIZE_4PB 92 sigreturn_addr = 0x1ull << 52; 93 pid = fork_child(); 94 expect_segv(pid); 95 96 // Return to 0xd space 97 sigreturn_addr = 0xdull << 60; 98 pid = fork_child(); 99 expect_segv(pid); 100 101 // Return to 0xe space 102 sigreturn_addr = 0xeull << 60; 103 pid = fork_child(); 104 expect_segv(pid); 105 106 // Return to 0xf space 107 sigreturn_addr = 0xfull << 60; 108 pid = fork_child(); 109 expect_segv(pid); 110 111 // Attempt to set PR=0 for 2nd loop (should be blocked by kernel) 112 sigreturn_msr_mask = ~MSR_PR; 113 } 114 115 printf("All children killed as expected\n"); 116 117 // Don't change address, just MSR, should return to user as normal 118 sigreturn_addr = 0; 119 sigreturn_msr_mask = ~MSR_PR; 120 pid = fork_child(); 121 waitpid(pid, &child_ret, 0); 122 FAIL_IF(!WIFEXITED(child_ret)); 123 FAIL_IF(WIFSIGNALED(child_ret)); 124 FAIL_IF(WEXITSTATUS(child_ret) != 0); 125 126 return 0; 127 } 128 129 int main(void) 130 { 131 return test_harness(test_sigreturn_kernel, "sigreturn_kernel"); 132 } 133