9 int failed = 0, duplicate = -1;
10 struct fr_file file = {.fd = -1};
11 const size_t page = fr_page, length = 4 * page;
12 unsigned char *shared = MAP_FAILED, *
private = MAP_FAILED;
13 CHECK(!fr_create(&file, FR_MEMFD) && (duplicate = dup(file.fd)) >= 0);
14 shared = mmap(NULL, length, PROT_READ | PROT_WRITE, MAP_SHARED, file.fd, 0);
15 private = mmap(NULL, 3 * page, PROT_READ | PROT_WRITE, MAP_PRIVATE, duplicate, page);
16 CHECK(shared != MAP_FAILED &&
private != MAP_FAILED);
17 CHECK(fr_matches(shared, 0, length, 0) && fr_matches(
private, page, 3 * page, 0));
19 CHECK(!fr_resident(shared, 4, 15,
"sealed shared before rejection") &&
20 !fr_resident(
private, 3, 7,
"sealed private before rejection"));
21 CHECK(!fcntl(file.fd, F_ADD_SEALS, F_SEAL_SHRINK));
22 const off_t position = 3 * page + 91;
23 CHECK(lseek(duplicate, position, SEEK_SET) == position);
24 const size_t sizes[] = {page + 137, 0};
25 for (
unsigned n = 0; n <
sizeof(sizes) /
sizeof(sizes[0]); ++n) {
26 CHECK(ftruncate(duplicate, sizes[n]) == -1 && errno == EPERM);
27 CHECK(!fr_resident(shared, 4, 15,
"sealed shared after rejection") &&
28 !fr_resident(
private, 3, 7,
"sealed private after rejection"));
29 CHECK(!fr_size(file.fd, length) && !fr_size(duplicate, length));
30 CHECK(fcntl(file.fd, F_GET_SEALS) == F_SEAL_SHRINK);
31 CHECK(lseek(file.fd, 0, SEEK_CUR) == position);
32 CHECK(fr_matches(shared, 0, length, 0) &&
private[23] == 0xa1 &&
33 fr_matches(
private, page, 23, 0) &&
34 fr_matches(
private + 24, page + 24, 3 * page - 24, 0));
35 CHECK(!fr_contents(file.fd, 0, length, 0));
38 if (
private != MAP_FAILED)
39 munmap(
private, 3 * page);
40 if (shared != MAP_FAILED)
41 munmap(shared, length);