12static int invalid_ranges(
void) {
13 int failed = 0, shmid = -1;
14 struct rp_file file = {.fd = -1};
15 const size_t page = rp_page;
16 unsigned char *mapping = MAP_FAILED, *
private = MAP_FAILED, *hole = MAP_FAILED;
17 unsigned char* shared_memory = (
void*)-1;
18 volatile unsigned char stack_byte = 0x73;
19 CHECK(!rp_create(&file, RP_MEMFD));
20 mapping = mmap(NULL, 4 * page, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 0);
21 private = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_PRIVATE, file.fd, 0);
22 hole = mmap(NULL, 3 * page, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 0);
23 CHECK(mapping != MAP_FAILED &&
private != MAP_FAILED && hole != MAP_FAILED);
24 CHECK(remap_file_pages(mapping, page, PROT_READ, 1, 0) == -1 && errno == EINVAL);
25 CHECK(remap_file_pages(mapping, 0, 0, 1, 0) == -1 && errno == EINVAL);
26 CHECK(remap_file_pages(mapping, page - 1, 0, 1, 0) == -1 && errno == EINVAL);
27 CHECK(remap_file_pages(mapping, 2 * page, 0, SIZE_MAX, 0) == -1 && errno == EINVAL);
28 CHECK(remap_file_pages(mapping, page, 0, (
size_t)INT64_MAX / page + 1, 0) == -1 &&
30 CHECK(remap_file_pages((
void*)(UINTPTR_MAX - page + 1), 2 * page, 0, 0, 0) == -1 &&
32 CHECK(remap_file_pages(NULL, page, 0, 0, 0) == -1 && errno == EINVAL);
33 CHECK(rp_matches(mapping, 0, 4 * page, 0));
35 CHECK(remap_file_pages(
private, page, 0, 1, 0) == -1 && errno == EINVAL);
36 CHECK(
private[71] == 0xd6 && mapping[71] == rp_pattern(71));
37 CHECK(!munmap(hole + page, page));
38 CHECK(remap_file_pages(hole, 3 * page, 0, 3, 0) == -1 && errno == EINVAL);
39 CHECK(rp_matches(hole, 0, page, 0) && rp_matches(hole + 2 * page, 2 * page, page, 0));
40 CHECK(!mprotect(mapping + page, page, PROT_READ));
41 CHECK(remap_file_pages(mapping, 2 * page, 0, 4, 0) == -1 && errno == EINVAL);
42 CHECK(rp_matches(mapping, 0, 4 * page, 0));
43 CHECK(!mprotect(mapping, 2 * page, PROT_READ | PROT_WRITE));
44 CHECK(!remap_file_pages(mapping, 2 * page, 0, 4, 0));
45 CHECK(rp_matches(mapping, 4 * page, 2 * page, 0));
46 CHECK(!mprotect(mapping, 2 * page, PROT_READ));
47 CHECK(!remap_file_pages(mapping, 2 * page, 0, 2, 0));
48 CHECK(rp_matches(mapping, 2 * page, 2 * page, 0) && !rp_fault(mapping, SIGSEGV, 1));
49 CHECK(!mprotect(mapping, page, PROT_NONE));
50 CHECK(!remap_file_pages(mapping, page, 0, 6, 0));
51 CHECK(!rp_fault(mapping, SIGSEGV, 0));
52 CHECK(!mprotect(mapping, page, PROT_READ));
53 CHECK(rp_matches(mapping, 6 * page, page, 0));
55 CHECK(remap_file_pages((
void*)&stack_byte, page, 0, 0, 0) == -1 && errno == EOPNOTSUPP);
56 CHECK(stack_byte == 0x73);
57 CHECK((shmid = shmget(IPC_PRIVATE, page, IPC_CREAT | 0600)) >= 0);
58 CHECK((shared_memory = shmat(shmid, NULL, 0)) != (
void*)-1);
59 CHECK(!shmctl(shmid, IPC_RMID, NULL));
61 shared_memory[0] = 0x49;
62 CHECK(remap_file_pages(shared_memory, page, 0, 0, 0) == -1 && errno == EOPNOTSUPP);
63 CHECK(shared_memory[0] == 0x49);
65 if (shared_memory != (
void*)-1)
68 shmctl(shmid, IPC_RMID, NULL);
69 if (hole != MAP_FAILED)
70 munmap(hole, 3 * page);
71 if (
private != MAP_FAILED)
72 munmap(
private, page);
73 if (mapping != MAP_FAILED)
74 munmap(mapping, 4 * page);
79static int separate_opens(
int backend) {
80 int failed = 0, other = -1, readonly = -1;
81 struct rp_file file = {.fd = -1};
82 const size_t page = rp_page;
83 unsigned char *area = MAP_FAILED, *read_mapping = MAP_FAILED;
84 struct stat first, second;
85 CHECK(!rp_create(&file, backend));
86 CHECK((other = rp_open_alias(&file)) >= 0 && (readonly = open(file.path, O_RDONLY)) >= 0);
87 CHECK(!fstat(file.fd, &first) && !fstat(other, &second) && first.st_ino == second.st_ino &&
88 first.st_dev == second.st_dev);
89 area = mmap(NULL, 2 * page, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
90 CHECK(area != MAP_FAILED);
91 CHECK(mmap(area, page, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, file.fd, 0) == area);
92 CHECK(mmap(area + page, page, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, other, page) ==
94 CHECK(remap_file_pages(area, 2 * page, 0, 4, 0) == -1 && errno == EINVAL);
95 CHECK(rp_matches(area, 0, 2 * page, 0));
96 read_mapping = mmap(NULL, page, PROT_READ, MAP_SHARED, readonly, 0);
97 CHECK(read_mapping != MAP_FAILED);
98 CHECK(remap_file_pages(read_mapping, page, 0, 1, 0) == -1 && errno == EINVAL);
99 CHECK(rp_matches(read_mapping, 0, page, 0));
101 if (read_mapping != MAP_FAILED)
102 munmap(read_mapping, page);
103 if (area != MAP_FAILED)
104 munmap(area, 2 * page);
113static int seals(
void) {
115 struct rp_file file = {.fd = -1};
116 const size_t page = rp_page;
117 unsigned char* mapping = MAP_FAILED;
118 CHECK(!rp_create(&file, RP_MEMFD));
119 mapping = mmap(NULL, 3 * page, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 0);
120 CHECK(mapping != MAP_FAILED && rp_matches(mapping, 0, 3 * page, 0));
121 CHECK(!fcntl(file.fd, F_ADD_SEALS, F_SEAL_FUTURE_WRITE));
122 CHECK(remap_file_pages(mapping, 3 * page, 0, 2, 0) == -1 && errno == EPERM);
123 CHECK(rp_matches(mapping, 0, 3 * page, 0));
124 CHECK(!mprotect(mapping, 3 * page, PROT_READ));
125 CHECK(mmap(mapping + 2 * page, page, PROT_READ, MAP_SHARED | MAP_FIXED, file.fd, 2 * page) ==
127 CHECK(remap_file_pages(mapping, 3 * page, 0, 2, 0) == -1 && errno == EINVAL);
128 CHECK(rp_matches(mapping, 0, 3 * page, 0));
129 CHECK(!remap_file_pages(mapping, 2 * page, 0, 2, MAP_NONBLOCK));
130 CHECK(!remap_file_pages(mapping, 3 * page, 0, 2, MAP_NONBLOCK));
131 CHECK(rp_matches(mapping, 2 * page, 3 * page, 0));
132 CHECK(mprotect(mapping, 3 * page, PROT_READ | PROT_WRITE) == -1 && errno == EACCES);
133 CHECK(!fcntl(file.fd, F_ADD_SEALS, F_SEAL_WRITE));
134 CHECK(!remap_file_pages(mapping, 3 * page, 0, 4, 0));
135 CHECK(rp_matches(mapping, 4 * page, 3 * page, 0));
137 if (mapping != MAP_FAILED)
138 munmap(mapping, 3 * page);
143int rp_admission(
void) {
144 return invalid_ranges() || separate_opens(RP_RAMFS) || separate_opens(RP_EXT2) || seals();