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 
sigusr1_handler(int signo,siginfo_t * si,void * uc_ptr)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 
fork_child(void)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 
expect_segv(pid_t pid)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 
test_sigreturn_kernel(void)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 
main(void)129 int main(void)
130 {
131 	return test_harness(test_sigreturn_kernel, "sigreturn_kernel");
132 }
133