• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // test prctl per process setting
2 #define _GNU_SOURCE 1
3 #include <stdlib.h>
4 #include <sys/mman.h>
5 #include <stdio.h>
6 #include <unistd.h>
7 #include <sys/prctl.h>
8 #include <setjmp.h>
9 #include <signal.h>
10 
11 #define err(x) perror("FAILURE: " x), exit(1)
12 #define fail(x) printf("FAILURE: " x "\n"), exit(1)
13 #define mb() asm volatile("" ::: "memory")
14 
15 #define MADV_POISON 100
16 
17 /*
18  * Set early/late kill mode for hwpoison memory corruption.
19  * This influences when the process gets killed on a memory corruption.
20  */
21 #define PR_MCE_KILL     33
22 # define PR_MCE_KILL_CLEAR   0
23 # define PR_MCE_KILL_SET     1
24 
25 # define PR_MCE_KILL_LATE    0
26 # define PR_MCE_KILL_EARLY   1
27 # define PR_MCE_KILL_DEFAULT 2
28 
29 #define PR_MCE_KILL_GET 34
30 
31 sigjmp_buf recover_ctx;
32 volatile int seq;
33 
handler(int sig)34 void handler(int sig)
35 {
36 	siglongjmp(recover_ctx, 1);
37 }
38 
test(int early)39 void test(int early)
40 {
41 	int PS = getpagesize();
42 	char *ptr = mmap(NULL, PS, PROT_READ|PROT_WRITE,
43 			 MAP_PRIVATE|MAP_ANONYMOUS|MAP_POPULATE, 0,0);
44 	if (ptr == (char *)-1L)
45 		err("mmap");
46 	signal(SIGBUS, handler);
47 	printf("ptr = %p\n", ptr);
48 	if (sigsetjmp(recover_ctx, 1) == 0) {
49 		seq = 0;
50 		printf("injection\n");
51 		if (madvise(ptr, PS, MADV_POISON) < 0)
52 			err("MADV_POISON");
53 		/* early kill should kill here */
54 		seq++;
55 		mb();
56 		printf("faulting\n");
57 		/* late kill should kill here */
58 		*ptr = 1;
59 		printf("finished\n");
60 	} else {
61 		printf("recovered\n");
62 		if (seq == 1 && early)
63 			fail("early mode set, but no early kill");
64 		if (seq == 0 && !early)
65 			fail("late mode set, but early kill");
66 	}
67 }
68 
main(void)69 int main(void)
70 {
71 	int err;
72 	err = prctl(PR_MCE_KILL_GET, 0, 0, 0, 0, 0);
73 	if (err < 0)
74 		err("PR_MCE_KILL_GET");
75 	if (err != PR_MCE_KILL_DEFAULT)
76 		fail("starting policy not default");
77 	if (prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_LATE, 0, 0, 0) < 0)
78 		err("PR_MCE_KILL_SET late");
79 	test(0);
80 	if (prctl(PR_MCE_KILL, PR_MCE_KILL_SET, PR_MCE_KILL_EARLY, 0, 0, 0) < 0)
81 		err("PR_MCE_KILL_SET early");
82 	test(1);
83 	err = prctl(PR_MCE_KILL_GET, 0, 0, 0,0,0);
84 	if (err < 0)
85 		err("PR_MCE_KILL_GET");
86 	if (err != PR_MCE_KILL_EARLY)
87 		fail("get mode not early after setting");
88 	if (prctl(PR_MCE_KILL, PR_MCE_KILL_CLEAR, 0, 0,0,0) < 0)
89 		err("PR_MCE_KILL_CLEAR");
90 	err = prctl(PR_MCE_KILL_GET, 0, 0, 0, 0, 0);
91 	if (err < 0)
92 		err("PR_MCE_KILL_GET");
93 	if (err != PR_MCE_KILL_DEFAULT)
94 		fail("ending policy not default");
95 	return 0;
96 }
97