示例#1
0
        public unsafe void TestMemfd()
        {
            int fd;

            try {
                fd = Syscall.memfd_create("mono-test", 0);
            } catch (EntryPointNotFoundException) {
                Assert.Ignore("memfd_create() not available");
                return;
            }
            if (fd < 0 && Stdlib.GetLastError() == Errno.ENOSYS)
            {
                // Might happen on a new libc + old kernel
                Assert.Ignore("memfd_create() returns ENOSYS");
            }
            if (fd < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            byte b = 42;

            if (Syscall.write(fd, &b, 1) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            // Should fail with EPERM because MFD_ALLOW_SEALING was not used
            var res = Syscall.fcntl(fd, FcntlCommand.F_ADD_SEALS, SealType.F_SEAL_WRITE);

            Assert.AreEqual(-1, res);
            Assert.AreEqual(Errno.EPERM, Stdlib.GetLastError());

            //Stdlib.system ("ls -l /proc/$PPID/fd/");

            if (Syscall.close(fd) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            // Call memfd_create with MFD_ALLOW_SEALING
            fd = Syscall.memfd_create("mono-test", MemfdFlags.MFD_CLOEXEC | MemfdFlags.MFD_ALLOW_SEALING);
            if (fd < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            if (Syscall.write(fd, &b, 1) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            res = Syscall.fcntl(fd, FcntlCommand.F_GET_SEALS);
            if (res < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
            // Need to convert the result to SealType
            SealType sealType = NativeConvert.ToSealType(res);

            Assert.AreEqual((SealType)0, sealType);

            if (Syscall.fcntl(fd, FcntlCommand.F_ADD_SEALS, SealType.F_SEAL_WRITE) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }

            // Should fail with EPERM because the file was sealed for writing
            var lres = Syscall.write(fd, &b, 1);

            Assert.AreEqual(-1, lres);
            Assert.AreEqual(Errno.EPERM, Stdlib.GetLastError());

            res = Syscall.fcntl(fd, FcntlCommand.F_GET_SEALS);
            if (res < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
            // Need to convert the result to SealType
            sealType = NativeConvert.ToSealType(res);
            Assert.AreEqual(SealType.F_SEAL_WRITE, sealType);

            //Stdlib.system ("ls -l /proc/$PPID/fd/");

            if (Syscall.close(fd) < 0)
            {
                UnixMarshal.ThrowExceptionForLastError();
            }
        }