gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/dev.cc (about) 1 // Copyright 2018 The gVisor Authors. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include <fcntl.h> 16 #include <sys/stat.h> 17 #include <sys/types.h> 18 #include <unistd.h> 19 20 #include <vector> 21 22 #include "gmock/gmock.h" 23 #include "gtest/gtest.h" 24 #include "test/util/file_descriptor.h" 25 #include "test/util/test_util.h" 26 27 namespace gvisor { 28 namespace testing { 29 30 namespace { 31 32 TEST(DevTest, LseekDevUrandom) { 33 const FileDescriptor fd = 34 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/urandom", O_RDONLY)); 35 EXPECT_THAT(lseek(fd.get(), -10, SEEK_CUR), SyscallSucceeds()); 36 EXPECT_THAT(lseek(fd.get(), -10, SEEK_SET), SyscallSucceeds()); 37 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceeds()); 38 } 39 40 TEST(DevTest, LseekDevNull) { 41 const FileDescriptor fd = 42 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDONLY)); 43 EXPECT_THAT(lseek(fd.get(), -10, SEEK_CUR), SyscallSucceeds()); 44 EXPECT_THAT(lseek(fd.get(), -10, SEEK_SET), SyscallSucceeds()); 45 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceeds()); 46 EXPECT_THAT(lseek(fd.get(), 0, SEEK_END), SyscallSucceeds()); 47 } 48 49 TEST(DevTest, LseekDevZero) { 50 const FileDescriptor fd = 51 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_RDONLY)); 52 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceeds()); 53 EXPECT_THAT(lseek(fd.get(), 0, SEEK_END), SyscallSucceeds()); 54 } 55 56 TEST(DevTest, LseekDevFull) { 57 const FileDescriptor fd = 58 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/full", O_RDONLY)); 59 EXPECT_THAT(lseek(fd.get(), 123, SEEK_SET), SyscallSucceedsWithValue(0)); 60 EXPECT_THAT(lseek(fd.get(), 123, SEEK_CUR), SyscallSucceedsWithValue(0)); 61 EXPECT_THAT(lseek(fd.get(), 123, SEEK_END), SyscallSucceedsWithValue(0)); 62 } 63 64 TEST(DevTest, LseekDevNullFreshFile) { 65 // Seeks to /dev/null always return 0. 66 const FileDescriptor fd1 = 67 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDONLY)); 68 const FileDescriptor fd2 = 69 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDONLY)); 70 71 EXPECT_THAT(lseek(fd1.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(0)); 72 EXPECT_THAT(lseek(fd1.get(), 1000, SEEK_CUR), SyscallSucceedsWithValue(0)); 73 EXPECT_THAT(lseek(fd2.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(0)); 74 75 const FileDescriptor fd3 = 76 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDONLY)); 77 EXPECT_THAT(lseek(fd3.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(0)); 78 } 79 80 TEST(DevTest, OpenTruncate) { 81 // Truncation is ignored on linux and gvisor for device files. 82 ASSERT_NO_ERRNO_AND_VALUE( 83 Open("/dev/null", O_CREAT | O_TRUNC | O_WRONLY, 0644)); 84 ASSERT_NO_ERRNO_AND_VALUE( 85 Open("/dev/zero", O_CREAT | O_TRUNC | O_WRONLY, 0644)); 86 ASSERT_NO_ERRNO_AND_VALUE( 87 Open("/dev/full", O_CREAT | O_TRUNC | O_WRONLY, 0644)); 88 } 89 90 TEST(DevTest, Pread64DevNull) { 91 const FileDescriptor fd = 92 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDONLY)); 93 char buf[1]; 94 EXPECT_THAT(pread64(fd.get(), buf, 1, 0), SyscallSucceedsWithValue(0)); 95 } 96 97 TEST(DevTest, Pread64DevZero) { 98 const FileDescriptor fd = 99 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_RDONLY)); 100 char buf[1]; 101 EXPECT_THAT(pread64(fd.get(), buf, 1, 0), SyscallSucceedsWithValue(1)); 102 } 103 104 TEST(DevTest, Pread64DevFull) { 105 // /dev/full behaves like /dev/zero with respect to reads. 106 const FileDescriptor fd = 107 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/full", O_RDONLY)); 108 char buf[1]; 109 EXPECT_THAT(pread64(fd.get(), buf, 1, 0), SyscallSucceedsWithValue(1)); 110 } 111 112 TEST(DevTest, ReadDevNull) { 113 const FileDescriptor fd = 114 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_RDONLY)); 115 std::vector<char> buf(1); 116 EXPECT_THAT(ReadFd(fd.get(), buf.data(), 1), SyscallSucceeds()); 117 } 118 119 // Do not allow random save as it could lead to partial reads. 120 TEST(DevTest, ReadDevZero) { 121 const FileDescriptor fd = 122 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_RDONLY)); 123 124 constexpr int kReadSize = 128 * 1024; 125 std::vector<char> buf(kReadSize, 1); 126 EXPECT_THAT(ReadFd(fd.get(), buf.data(), kReadSize), 127 SyscallSucceedsWithValue(kReadSize)); 128 EXPECT_EQ(std::vector<char>(kReadSize, 0), buf); 129 } 130 131 TEST(DevTest, WriteDevNull) { 132 const FileDescriptor fd = 133 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/null", O_WRONLY)); 134 EXPECT_THAT(WriteFd(fd.get(), "a", 1), SyscallSucceedsWithValue(1)); 135 } 136 137 TEST(DevTest, WriteDevZero) { 138 const FileDescriptor fd = 139 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/zero", O_WRONLY)); 140 EXPECT_THAT(WriteFd(fd.get(), "a", 1), SyscallSucceedsWithValue(1)); 141 } 142 143 TEST(DevTest, WriteDevFull) { 144 const FileDescriptor fd = 145 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/full", O_WRONLY)); 146 EXPECT_THAT(WriteFd(fd.get(), "a", 1), SyscallFailsWithErrno(ENOSPC)); 147 } 148 149 TEST(DevTest, TTYExists) { 150 struct stat statbuf = {}; 151 ASSERT_THAT(stat("/dev/tty", &statbuf), SyscallSucceeds()); 152 // Check that it's a character device with rw-rw-rw- permissions. 153 EXPECT_EQ(statbuf.st_mode, S_IFCHR | 0666); 154 } 155 156 TEST(DevTest, OpenDevFuse) { 157 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/fuse", O_RDONLY)); 158 } 159 160 TEST(DevTest, ReadDevFuseWithoutMount) { 161 // Note(gvisor.dev/issue/3076) This won't work in the sentry until the new 162 // device registration is complete. 163 SKIP_IF(IsRunningOnGvisor()); 164 165 const FileDescriptor fd = 166 ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/fuse", O_RDONLY)); 167 168 std::vector<char> buf(1); 169 EXPECT_THAT(ReadFd(fd.get(), buf.data(), sizeof(buf)), 170 SyscallFailsWithErrno(EPERM)); 171 } 172 173 } // namespace 174 } // namespace testing 175 176 } // namespace gvisor