31static size_t page_size = 0;
32static size_t mapping_size = 0;
40static void* adjust_pointer(
void* p, ssize_t amt) {
41 return (
void*)(((uintptr_t)p) + amt);
44static void sigsegv(
int s) {
51 printf(
"PROT_NONE works, checking read...\n");
52 mprotect(p, page_size, PROT_READ);
59 printf(
"PROT_READ works, checking write...\n");
60 mprotect(p, page_size, PROT_WRITE);
62 *((
volatile char*)p) =
'Y';
64 mprotect(p, page_size, PROT_NONE);
68 printf(
"PROT_WRITE works, checking exec...\n");
69 mprotect(p, page_size, PROT_WRITE);
71 *((
volatile unsigned char*)p) = 0xC3;
73 mprotect(p, page_size, PROT_EXEC);
79 printf(
"Attempting to return to original context...\n");
80 mprotect(p, page_size, PROT_READ | PROT_WRITE);
87static void sigsegv_jumper(
int s) {
91static void status(
const char* s) {
99 const long configured_page_size = sysconf(_SC_PAGESIZE);
100 if (configured_page_size <= 0)
102 page_size = (size_t)configured_page_size;
103 mapping_size = 16 * page_size;
105 p = mmap(0, mapping_size, PROT_NONE, MAP_PRIVATE | MAP_ANON, 0, 0);
110 static struct sigaction act;
111 sigprocmask(0, 0, &act.sa_mask);
112 act.sa_handler = sigsegv;
114 act.sa_flags = SA_NODEFER;
118 sigaction(SIGSEGV, &act, 0);
121 printf(
"Testing mprotect(2)...\n");
124 printf(
"mprotect(2) initial test was successful!\n");
126 printf(
"Testing mprotect(2) on ranges of pages...\n");
130 act.sa_handler = sigsegv_jumper;
131 sigaction(SIGSEGV, &act, 0);
134 mprotect(p, mapping_size, PROT_WRITE);
135 status(
"Test A... ");
138 mprotect(p, mapping_size, PROT_NONE);
141 mprotect(adjust_pointer(p, -((ssize_t)page_size)), mapping_size + (2 * page_size), PROT_WRITE);
142 status(
"Test B... ");
143 if (setjmp(buf) == 1)
146 p[mapping_size - 1] =
'X';
148 mprotect(p, mapping_size, PROT_NONE);
151 mprotect(adjust_pointer(p, -((ssize_t)page_size)), 5 * page_size, PROT_WRITE);
152 status(
"Test C... ");
153 if (setjmp(buf) == 1)
156 if (setjmp(buf) == 0) {
157 p[(5 * page_size) + 1] =
'X';
161 mprotect(p, mapping_size, PROT_NONE);
164 mprotect(adjust_pointer(p, 5 * page_size), 6 * page_size, PROT_WRITE);
165 status(
"Test D... ");
166 if (setjmp(buf) == 1)
168 p[5 * page_size] =
'X';
169 if (setjmp(buf) == 0) {
174 mprotect(p, mapping_size, PROT_NONE);
177 mprotect(adjust_pointer(p, 2 * page_size), 6 * page_size, PROT_WRITE);
178 status(
"Test E... ");
179 if (setjmp(buf) == 1)
181 p[2 * page_size] =
'X';
182 if (setjmp(buf) == 0) {
187 if (setjmp(buf) == 0) {
188 p[(8 * page_size) + 1] =
'X';
192 mprotect(p, mapping_size, PROT_NONE);
194 printf(
"mprotect(2) page range test was successful!\n");
197 signal(SIGSEGV, SIG_DFL);