gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/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 const TempPath file = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFile()); 82 const FileDescriptor fd = 83 ASSERT_NO_ERRNO_AND_VALUE(Open(file.path(), O_PATH)); 84 85 char buf[1024]; 86 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallFailsWithErrno(EBADF)); 87 } 88 89 TEST_F(Pread64Test, DirNotReadable) { 90 const FileDescriptor fd = 91 ASSERT_NO_ERRNO_AND_VALUE(Open(GetAbsoluteTestTmpdir(), O_RDONLY)); 92 93 char buf[1024]; 94 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallFailsWithErrno(EISDIR)); 95 } 96 97 TEST_F(Pread64Test, BadOffset) { 98 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDONLY)); 99 100 char buf[1024]; 101 EXPECT_THAT(pread64(fd.get(), buf, 1024, -1), SyscallFailsWithErrno(EINVAL)); 102 } 103 104 TEST_F(Pread64Test, OffsetNotIncremented) { 105 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDWR)); 106 107 char msg[] = "hello world"; 108 EXPECT_THAT(write(fd.get(), msg, strlen(msg)), 109 SyscallSucceedsWithValue(strlen(msg))); 110 int offset; 111 EXPECT_THAT(offset = lseek(fd.get(), 0, SEEK_CUR), SyscallSucceeds()); 112 113 char buf1[1024]; 114 EXPECT_THAT(pread64(fd.get(), buf1, 1024, 0), 115 SyscallSucceedsWithValue(strlen(msg))); 116 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(offset)); 117 118 char buf2[1024]; 119 EXPECT_THAT(pread64(fd.get(), buf2, 1024, 3), 120 SyscallSucceedsWithValue(strlen(msg) - 3)); 121 EXPECT_THAT(lseek(fd.get(), 0, SEEK_CUR), SyscallSucceedsWithValue(offset)); 122 } 123 124 TEST_F(Pread64Test, EndOfFile) { 125 const FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(name_, O_RDONLY)); 126 127 char buf[1024]; 128 EXPECT_THAT(pread64(fd.get(), buf, 1024, 0), SyscallSucceedsWithValue(0)); 129 } 130 131 int memfd_create(const std::string& name, unsigned int flags) { 132 return syscall(__NR_memfd_create, name.c_str(), flags); 133 } 134 135 TEST_F(Pread64Test, Overflow) { 136 int f = memfd_create("negative", 0); 137 const FileDescriptor fd(f); 138 139 EXPECT_THAT(ftruncate(fd.get(), 0x7fffffffffffffffull), SyscallSucceeds()); 140 141 char buf[10]; 142 EXPECT_THAT(pread64(fd.get(), buf, sizeof(buf), 0x7fffffffffffffffull), 143 SyscallFailsWithErrno(EINVAL)); 144 } 145 146 TEST(Pread64TestNoTempFile, CantReadSocketPair) { 147 int sock_fds[2]; 148 EXPECT_THAT(socketpair(AF_UNIX, SOCK_STREAM, 0, sock_fds), SyscallSucceeds()); 149 150 char buf[1024]; 151 EXPECT_THAT(pread64(sock_fds[0], buf, 1024, 0), 152 SyscallFailsWithErrno(ESPIPE)); 153 EXPECT_THAT(pread64(sock_fds[1], buf, 1024, 0), 154 SyscallFailsWithErrno(ESPIPE)); 155 156 EXPECT_THAT(close(sock_fds[0]), SyscallSucceeds()); 157 EXPECT_THAT(close(sock_fds[1]), SyscallSucceeds()); 158 } 159 160 TEST(Pread64TestNoTempFile, CantReadPipe) { 161 char buf[1024]; 162 163 int pipe_fds[2]; 164 EXPECT_THAT(pipe(pipe_fds), SyscallSucceeds()); 165 166 EXPECT_THAT(pread64(pipe_fds[0], buf, 1024, 0), 167 SyscallFailsWithErrno(ESPIPE)); 168 169 EXPECT_THAT(close(pipe_fds[0]), SyscallSucceeds()); 170 EXPECT_THAT(close(pipe_fds[1]), SyscallSucceeds()); 171 } 172 173 } // namespace 174 175 } // namespace testing 176 } // namespace gvisor