9static int additive_and_size(
void) {
10 int failed = 0, fd = -1;
12 memset(original,
'a',
sizeof(original));
13 CHECK((fd = mf_make(
sizeof(original))) >= 0);
14 CHECK(pwrite(fd, original,
sizeof(original), 0) ==
sizeof(original));
15 CHECK(!fcntl(fd, F_ADD_SEALS, 0) && fcntl(fd, F_GET_SEALS) == 0);
16 CHECK(fcntl(fd, F_ADD_SEALS, F_SEAL_GROW | 0x20) == -1 && errno == EINVAL);
17 CHECK(fcntl(fd, F_GET_SEALS) == 0 && !mf_size(fd, 64));
18 CHECK(!fcntl(fd, F_ADD_SEALS, F_SEAL_GROW));
19 CHECK(!fcntl(fd, F_ADD_SEALS, F_SEAL_GROW));
20 CHECK(ftruncate(fd, 65) == -1 && errno == EPERM);
21 CHECK(pwrite(fd,
"z", 1, 64) == -1 && errno == EPERM);
22 CHECK(!mf_size(fd, 64) && !mf_contents(fd, 0, original, 64));
23 CHECK(!ftruncate(fd, 32));
24 CHECK(!fcntl(fd, F_ADD_SEALS, F_SEAL_SHRINK));
25 CHECK(ftruncate(fd, 31) == -1 && errno == EPERM);
26 CHECK(!mf_size(fd, 32) && !mf_contents(fd, 0, original, 32));
27 CHECK(!ftruncate(fd, 32));
28 CHECK(lseek(fd, 31, SEEK_SET) == 31);
29 CHECK(write(fd,
"zz", 2) == -1 && errno == EPERM);
30 CHECK(lseek(fd, 0, SEEK_CUR) == 31 && !mf_contents(fd, 0, original, 32));
31 CHECK(pwrite(fd,
"b", 1, 0) == 1);
32 CHECK(!fcntl(fd, F_ADD_SEALS, F_SEAL_WRITE | F_SEAL_FUTURE_WRITE | F_SEAL_SEAL));
33 const int all = F_SEAL_GROW | F_SEAL_SHRINK | F_SEAL_WRITE | F_SEAL_FUTURE_WRITE | F_SEAL_SEAL;
34 CHECK(fcntl(fd, F_GET_SEALS) == all);
35 CHECK(fcntl(fd, F_ADD_SEALS, 0) == -1 && errno == EPERM);
36 CHECK(fcntl(fd, F_ADD_SEALS, F_SEAL_WRITE) == -1 && errno == EPERM);
37 CHECK(fcntl(fd, F_GET_SEALS) == all);
43static int denied_writes(
int seal) {
44 int failed = 0, fd = -1;
45 const size_t page = sysconf(_SC_PAGESIZE);
46 char*
private = MAP_FAILED;
47 char original[64], zeros[32] = {0};
48 memset(original,
'q',
sizeof(original));
49 struct iovec vector[] = {{
"x", 1}, {
"y", 1}};
50 CHECK((fd = mf_make(page)) >= 0);
51 CHECK(pwrite(fd, original,
sizeof(original), 0) ==
sizeof(original));
52 CHECK(!fcntl(fd, F_ADD_SEALS, seal));
53 CHECK(lseek(fd, 7, SEEK_SET) == 7);
54 CHECK(write(fd,
"x", 1) == -1 && errno == EPERM);
55 CHECK(lseek(fd, 0, SEEK_CUR) == 7);
56 CHECK(pwrite(fd,
"x", 1, 0) == -1 && errno == EPERM);
57 CHECK(writev(fd, vector, 2) == -1 && errno == EPERM);
58 CHECK(pwritev(fd, vector, 2, 0) == -1 && errno == EPERM);
59 CHECK(lseek(fd, 0, SEEK_CUR) == 7 && !mf_contents(fd, 0, original, 64));
60 CHECK(!fcntl(fd, F_SETFL, O_APPEND));
61 CHECK(write(fd,
"x", 1) == -1 && errno == EPERM);
62 CHECK(lseek(fd, 0, SEEK_CUR) == 7 && !mf_size(fd, page));
63 CHECK(write(fd,
"", 0) == 0 && pwrite(fd,
"", 0, page + 1) == 0);
64 CHECK(!mf_size(fd, page) && fcntl(fd, F_GET_SEALS) == seal);
65 CHECK(!fcntl(fd, F_SETFL, 0));
66 CHECK(!ftruncate(fd, 32) && !ftruncate(fd, 64));
67 CHECK(!mf_contents(fd, 0, original, 32) && !mf_contents(fd, 32, zeros, 32));
68 CHECK(!ftruncate(fd, page));
69 private = mmap(NULL, page, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
70 CHECK(
private != MAP_FAILED &&
private[0] ==
'q');
72 CHECK(
private[0] ==
'p' && !mf_contents(fd, 0,
"q", 1));
74 if (
private != MAP_FAILED)
75 munmap(
private, page);
80int memfd_seals(
void) {
81 return additive_and_size() || denied_writes(F_SEAL_WRITE) || denied_writes(F_SEAL_FUTURE_WRITE);