10static int names_and_flags(
void) {
11 int failed = 0, plain = -1, first = -1, second = -1, long_fd = -1;
12 const size_t page = sysconf(_SC_PAGESIZE);
13 char* denied = MAP_FAILED;
14 mode_t mask = umask(0077);
15 struct stat st, other;
17 CHECK((plain = memfd_create(
"", 0)) >= 0);
18 CHECK(fcntl(plain, F_GET_SEALS) == F_SEAL_SEAL);
19 CHECK(fcntl(plain, F_ADD_SEALS, F_SEAL_GROW) == -1 && errno == EPERM);
20 CHECK(fcntl(plain, F_ADD_SEALS, 0) == -1 && errno == EPERM);
21 CHECK(fcntl(plain, F_GET_SEALS) == F_SEAL_SEAL);
22 CHECK((fcntl(plain, F_GETFL) & O_ACCMODE) == O_RDWR);
23 CHECK(fcntl(plain, F_GETFD) == 0);
24 CHECK(!fstat(plain, &st) && S_ISREG(st.st_mode) && (st.st_mode & 07777) == 0777 &&
25 st.st_nlink == 0 && st.st_size == 0 && st.st_uid == geteuid() && st.st_gid == getegid());
26 CHECK(read(plain, name, 1) == 0);
27 CHECK(lseek(plain, 17, SEEK_SET) == 17 && lseek(plain, 0, SEEK_END) == 0);
28 CHECK((first = memfd_create(
"same label", MFD_ALLOW_SEALING | MFD_CLOEXEC)) >= 0);
29 CHECK((second = memfd_create(
"same label", MFD_ALLOW_SEALING)) >= 0);
30 CHECK(fcntl(first, F_GET_SEALS) == 0 && fcntl(second, F_GET_SEALS) == 0);
31 CHECK(fcntl(first, F_GETFD) == FD_CLOEXEC && fcntl(second, F_GETFD) == 0);
32 CHECK(!fstat(first, &st) && !fstat(second, &other) &&
33 (st.st_ino != other.st_ino || st.st_dev != other.st_dev));
34 CHECK(write(first,
"a", 1) == 1 && !mf_size(second, 0));
35 CHECK(!fcntl(first, F_ADD_SEALS, F_SEAL_GROW) && fcntl(second, F_GET_SEALS) == 0);
36 memset(name,
'n',
sizeof(name));
38 CHECK((long_fd = memfd_create(name, MFD_ALLOW_SEALING)) >= 0);
41 CHECK(memfd_create(name, 0) == -1 && errno == EINVAL);
42 CHECK(memfd_create(
"invalid", 0x80000000U) == -1 && errno == EINVAL);
43 CHECK(memfd_create(
"huge", MFD_HUGETLB) == -1 && errno == EINVAL);
44 denied = mmap(NULL, page, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
45 CHECK(denied != MAP_FAILED);
46 CHECK(memfd_create(denied, 0) == -1 && errno == EFAULT);
49 if (denied != MAP_FAILED)
61static int ordinary_io(
void) {
62 int failed = 0, fd = -1, alias = -1, regular = -1;
65 snprintf(path,
sizeof(path),
"/tmp/memfd-regular-%ld", (
long)getpid());
66 CHECK((fd = memfd_create(
"io", MFD_ALLOW_SEALING)) >= 0);
67 CHECK(write(fd,
"abcd", 4) == 4 && pwrite(fd,
"XY", 2, 1) == 2);
68 CHECK(lseek(fd, 0, SEEK_CUR) == 4 && !mf_contents(fd, 0,
"aXYd", 4));
69 CHECK((alias = dup(fd)) >= 0);
70 CHECK(lseek(alias, 1, SEEK_SET) == 1 && read(fd, bytes, 2) == 2 && !memcmp(bytes,
"XY", 2));
71 CHECK(lseek(alias, 0, SEEK_CUR) == 3);
72 struct iovec vector[] = {{
"12", 2}, {
"34", 2}};
73 CHECK(pwritev(fd, vector, 2, 4) == 4 && lseek(fd, 0, SEEK_CUR) == 3);
74 CHECK(!mf_contents(fd, 0,
"aXYd1234", 8));
75 CHECK(lseek(fd, 0, SEEK_END) == 8 && writev(fd, vector, 2) == 4);
76 CHECK(!ftruncate(fd, 16) && !mf_contents(fd, 12,
"\0\0\0\0", 4));
77 struct iovec input[] = {{bytes, 3}, {bytes + 3, 5}};
78 CHECK(preadv(fd, input, 2, 4) == 8 && !memcmp(bytes,
"12341234", 8));
79 CHECK(!fcntl(alias, F_SETFL, O_APPEND));
80 CHECK((fcntl(fd, F_GETFL) & O_APPEND) && write(fd,
"!", 1) == 1 && !mf_size(fd, 17));
81 CHECK(!mf_contents(fd, 16,
"!", 1));
82 CHECK((regular = open(path, O_CREAT | O_EXCL | O_RDWR, 0600)) >= 0);
83 CHECK(fcntl(regular, F_GET_SEALS) == -1 && errno == EINVAL);
84 CHECK(fcntl(regular, F_ADD_SEALS, F_SEAL_GROW) == -1 && errno == EINVAL);
85 CHECK(fcntl(-1, F_GET_SEALS) == -1 && errno == EBADF);
97int memfd_creation(
void) {
98 return names_and_flags() || ordinary_io();