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