9static int subrange_and_file_victims(
void) {
10 int failed = 0, fd = -1;
11 const size_t p = vm_page;
12 unsigned char *source = MAP_FAILED, *target = MAP_FAILED, *backing = MAP_FAILED;
13 unsigned char resident;
14 CHECK((fd = vm_file(6, NULL)) >= 0);
15 CHECK((source = mmap(NULL, 4 * p, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, p)) != MAP_FAILED);
16 CHECK((target = mmap(NULL, 5 * p, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) != MAP_FAILED);
17 CHECK((backing = mmap(NULL, 6 * p, PROT_READ, MAP_SHARED, fd, 0)) != MAP_FAILED);
20 CHECK(close(fd) == 0);
22 CHECK(mremap(source + p, 2 * p, 2 * p, MREMAP_FIXED | MREMAP_MAYMOVE, target + p) == target + p);
23 CHECK(source[0] == 0x99 && source[3 * p] == 0x24);
24 CHECK(target[0] == 0x20 && target[p] == 0x22 && target[2 * p] == 0x77 && target[3 * p] == 0x23 &&
25 target[4 * p] == 0x24);
26 CHECK(backing[p] == 0x21 && backing[3 * p] == 0x23);
28 CHECK(backing[2 * p + 1] == 0x22);
29 CHECK(mincore(source + p, p, &resident) == -1 && errno == ENOMEM);
30 CHECK(mmap(source + p, 2 * p, PROT_READ | PROT_WRITE,
31 MAP_PRIVATE | MAP_ANONYMOUS | MAP_FIXED_NOREPLACE, -1, 0) == source + p);
32 CHECK(vm_uniform(source + p, 2 * p, 0) && source[3 * p] == 0x24);
36 if (source != MAP_FAILED)
37 munmap(source, 4 * p);
38 if (target != MAP_FAILED)
39 munmap(target, 5 * p);
40 if (backing != MAP_FAILED)
41 munmap(backing, 6 * p);
45static int shared_growth_and_eof(
void) {
46 int failed = 0, fd = -1;
47 const size_t p = vm_page;
48 unsigned char *source = MAP_FAILED, *target = MAP_FAILED, *alias = MAP_FAILED;
49 unsigned char resident[3];
50 CHECK((fd = vm_file(3, NULL)) >= 0);
51 CHECK((source = mmap(NULL, 2 * p, PROT_READ | PROT_WRITE, MAP_SHARED, fd, p)) != MAP_FAILED);
52 CHECK((alias = mmap(NULL, 3 * p, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0)) != MAP_FAILED);
53 CHECK((target = mmap(NULL, 3 * p, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED);
55 CHECK(alias[p] == 0xb0 && close(fd) == 0);
57 CHECK(mremap(source, 2 * p, 3 * p, MREMAP_FIXED | MREMAP_MAYMOVE, target) == target);
58 CHECK(target[0] == 0xb0 && target[p] == 0x22);
61 CHECK(alias[p] == 0xb1 && target[p] == 0xb2);
62 CHECK(mincore(target, 3 * p, resident) == 0 && resident[2] == 0);
63 CHECK(vm_fault(target + 2 * p, 0, SIGBUS) == 0);
67 if (source != MAP_FAILED)
68 munmap(source, 2 * p);
69 if (target != MAP_FAILED)
70 munmap(target, 3 * p);
71 if (alias != MAP_FAILED)
76static int retained_protections(
void) {
77 int failed = 0, fd = -1, readonly = -1;
78 const size_t p = vm_page;
79 unsigned char *source = MAP_FAILED, *target = MAP_FAILED;
80 unsigned char resident[2];
81 CHECK((fd = vm_file(3, &readonly)) >= 0);
82 CHECK((source = mmap(NULL, 2 * p, PROT_READ, MAP_SHARED, readonly, p)) != MAP_FAILED);
83 CHECK((target = mmap(NULL, 2 * p, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)) != MAP_FAILED);
84 CHECK(source[0] == 0x21);
85 CHECK(close(fd) == 0 && close(readonly) == 0);
87 CHECK(mremap(source, 2 * p, 2 * p, MREMAP_FIXED | MREMAP_MAYMOVE, target) == target);
88 CHECK(target[0] == 0x21 && target[p] == 0x22);
89 CHECK(mprotect(target, 2 * p, PROT_READ | PROT_WRITE) == -1 && errno == EACCES);
90 CHECK(vm_fault(target, 1, SIGSEGV) == 0);
91 CHECK(mprotect(target, 2 * p, PROT_NONE) == 0);
92 CHECK(mremap(target, 2 * p, 2 * p, MREMAP_FIXED | MREMAP_MAYMOVE, source) == source);
93 CHECK(mincore(source, 2 * p, resident) == 0 && resident[0] == 1 && resident[1] == 1);
94 CHECK(vm_fault(source, 0, SIGSEGV) == 0);
95 CHECK(mprotect(source, 2 * p, PROT_READ) == 0 && source[0] == 0x21 && source[p] == 0x22);
96 CHECK(mprotect(source, 2 * p, PROT_READ | PROT_WRITE) == -1 && errno == EACCES);
102 if (source != MAP_FAILED)
103 munmap(source, 2 * p);
104 if (target != MAP_FAILED)
105 munmap(target, 2 * p);
109int vm_test_remap_file(
void) {
110 return subrange_and_file_victims() || shared_growth_and_eof() || retained_protections();