1 #include <sys/mman.h>
2 #include <signal.h>
3 #include <stdio.h>
4 #include <unistd.h>
5
6 enum {
7 kMmapSize = 0x1000,
8 kMagicValue = 47,
9 };
10
11 void *address;
12 volatile sig_atomic_t signaled = 0;
13
handler(int sig)14 void handler(int sig)
15 {
16 signaled = 1;
17 if (munmap(address, kMmapSize) != 0)
18 {
19 perror("munmap");
20 _exit(5);
21 }
22
23 void* newaddr = mmap(address, kMmapSize, PROT_READ | PROT_WRITE,
24 MAP_ANON | MAP_FIXED | MAP_PRIVATE, -1, 0);
25 if (newaddr != address)
26 {
27 fprintf(stderr, "Newly mmaped address (%p) does not equal old address (%p).\n",
28 newaddr, address);
29 _exit(6);
30 }
31 *(int*)newaddr = kMagicValue;
32 }
33
main()34 int main()
35 {
36 if (signal(SIGSEGV, handler) == SIG_ERR)
37 {
38 perror("signal");
39 return 1;
40 }
41
42 address = mmap(NULL, kMmapSize, PROT_NONE, MAP_ANON | MAP_PRIVATE, -1, 0);
43 if (address == MAP_FAILED)
44 {
45 perror("mmap");
46 return 2;
47 }
48
49 // This should first trigger a segfault. Our handler will make the memory readable and write
50 // the magic value into memory.
51 if (*(int*)address != kMagicValue)
52 return 3;
53
54 if (! signaled)
55 return 4;
56
57 return 0;
58 }
59