github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/pread64.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 <errno.h> 16 #include <fcntl.h> 17 #include <linux/unistd.h> 18 #include <sys/mman.h> 19 #include <sys/socket.h> 20 #include <sys/types.h> 21 #include <unistd.h> 22 23 #include "gtest/gtest.h" 24 #include "test/util/file_descriptor.h" 25 #include "test/util/temp_path.h" 26 #include "test/util/test_util.h" 27 28 namespace gvisor { 29 namespace testing { 30 31 namespace { 32 33 class Pread64Test : public ::testing::Test { 34 void SetUp() override { 35 name_ = NewTempAbsPath(); 36 ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_CREAT, 0644)); 37 } 38 39 void TearDown() override { unlink(name_.c_str()); } 40 41 public: 42 std::string name_; 43 }; 44 45 TEST(Pread64TestNoTempFile, BadFileDescriptor) { 46 char buf[1024]; 47 EXPECT_THAT(pread64(-1, buf, 1024, 0), SyscallFailsWithErrno(EBADF)); 48 } 49 50 TEST_F(Pread64Test, ZeroBuffer) { 51 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDWR)); 52 53 char msg[] = "hello world"; 54 EXPECT_THAT(pwrite64(fd.get(), msg, strlen(msg), 0), 55 SyscallSucceedsWithValue(strlen(msg))); 56 57 char buf[10]; 58 EXPECT_THAT(pread64(fd.get(), buf, 0, 0), SyscallSucceedsWithValue(0)); 59 } 60 61 TEST_F(Pread64Test, BadBuffer) { 62 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDWR)); 63 64 char msg[] = "hello world"; 65 EXPECT_THAT(pwrite64(fd.get(), msg, strlen(msg), 0), 66 SyscallSucceedsWithValue(strlen(msg))); 67 68 char* bad_buffer = nullptr; 69 EXPECT_THAT(pread64(fd.get(), bad_buffer, 1024, 0), 70 SyscallFailsWithErrno(EFAULT)); 71 } 72 73 TEST_F(Pread64Test, WriteOnlyNotReadable) { 74 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_WRONLY)); 75 76 char buf[1024]; 77 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallFailsWithErrno(EBADF)); 78 } 79 80 TEST_F(Pread64Test, Pread64WithOpath) { 81 SKIP_IF(IsRunningWithVFS1()); 82 const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); 83 const FileDescriptor fd = 84 ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_PATH)); 85 86 char buf[1024]; 87 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallFailsWithErrno(EBADF)); 88 } 89 90 TEST_F(Pread64Test, DirNotReadable) { 91 const FileDescriptor fd = 92 ASSERT_NO_ERRNO_AND_VALUE(Open(GetAbsoluteTestTmpdir(), O_RDONLY)); 93 94 char buf[1024]; 95 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallFailsWithErrno(EISDIR)); 96 } 97 98 TEST_F(Pread64Test, BadOffset) { 99 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDONLY)); 100 101 char buf[1024]; 102 EXPECT_THAT(pread64(fd.get(), buf, 1024, -1), SyscallFailsWithErrno(EINVAL)); 103 } 104 105 TEST_F(Pread64Test, OffsetNotIncremented) { 106 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDWR)); 107 108 char msg[] = "hello world"; 109 EXPECT_THAT(write(fd.get(), msg, strlen(msg)), 110 SyscallSucceedsWithValue(strlen(msg))); 111 int offset; 112 EXPECT_THAT(offset = lseek(fd.get(), 0, SEEK_CUR), SyscallSucceeds()); 113 114 char buf1[1024]; 115 EXPECT_THAT(pread64(fd.get(), buf1, 1024, 0), 116 SyscallSucceedsWithValue(strlen(msg))); 117 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(offset)); 118 119 char buf2[1024]; 120 EXPECT_THAT(pread64(fd.get(), buf2, 1024, 3), 121 SyscallSucceedsWithValue(strlen(msg) - 3)); 122 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(offset)); 123 } 124 125 TEST_F(Pread64Test, EndOfFile) { 126 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDONLY)); 127 128 char buf[1024]; 129 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallSucceedsWithValue(0)); 130 } 131 132 int memfd_create(const std::string& name, unsigned int flags) { 133 return syscall(__NR_memfd_create, name.c_str(), flags); 134 } 135 136 TEST_F(Pread64Test, Overflow) { 137 int f = memfd_create("negative", 0); 138 const FileDescriptor fd(f); 139 140 EXPECT_THAT(ftruncate(fd.get(), 0x7fffffffffffffffull), SyscallSucceeds()); 141 142 char buf[10]; 143 EXPECT_THAT(pread64(fd.get(), buf, sizeof(buf), 0x7fffffffffffffffull), 144 SyscallFailsWithErrno(EINVAL)); 145 } 146 147 TEST(Pread64TestNoTempFile, CantReadSocketPair) { 148 int sock_fds[2]; 149 EXPECT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds), SyscallSucceeds()); 150 151 char buf[1024]; 152 EXPECT_THAT(pread64(sock_fds[0], buf, 1024, 0), 153 SyscallFailsWithErrno(ESPIPE)); 154 EXPECT_THAT(pread64(sock_fds[1], buf, 1024, 0), 155 SyscallFailsWithErrno(ESPIPE)); 156 157 EXPECT_THAT(close(sock_fds[0]), SyscallSucceeds()); 158 EXPECT_THAT(close(sock_fds[1]), SyscallSucceeds()); 159 } 160 161 TEST(Pread64TestNoTempFile, CantReadPipe) { 162 char buf[1024]; 163 164 int pipe_fds[2]; 165 EXPECT_THAT(pipe(pipe_fds), SyscallSucceeds()); 166 167 EXPECT_THAT(pread64(pipe_fds[0], buf, 1024, 0), 168 SyscallFailsWithErrno(ESPIPE)); 169 170 EXPECT_THAT(close(pipe_fds[0]), SyscallSucceeds()); 171 EXPECT_THAT(close(pipe_fds[1]), SyscallSucceeds()); 172 } 173 174 } // namespace 175 176 } // namespace testing 177 } // namespace gvisor