github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/verity_getdents.cc (about)

     1  // Copyright 2021 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 <dirent.h>
    16  #include <stdint.h>
    17  #include <stdlib.h>
    18  #include <sys/mount.h>
    19  #include <sys/syscall.h>
    20  
    21  #include <string>
    22  #include <vector>
    23  
    24  #include "gmock/gmock.h"
    25  #include "gtest/gtest.h"
    26  #include "test/util/capability_util.h"
    27  #include "test/util/fs_util.h"
    28  #include "test/util/temp_path.h"
    29  #include "test/util/test_util.h"
    30  #include "test/util/verity_util.h"
    31  
    32  namespace gvisor {
    33  namespace testing {
    34  
    35  namespace {
    36  
    37  class GetDentsTest : public ::testing::Test {
    38   protected:
    39    void SetUp() override {
    40      // Verity is implemented in VFS2.
    41      SKIP_IF(IsRunningWithVFS1());
    42  
    43      SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
    44      // Mount a tmpfs file system, to be wrapped by a verity fs.
    45      tmpfs_dir_ = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
    46      ASSERT_THAT(mount("", tmpfs_dir_.path().c_str(), "tmpfs", 0, ""),
    47                  SyscallSucceeds());
    48  
    49      // Create a new file in the tmpfs mount.
    50      file_ = ASSERT_NO_ERRNO_AND_VALUE(
    51          TempPath::CreateFileWith(tmpfs_dir_.path(), kContents, 0777));
    52      filename_ = Basename(file_.path());
    53    }
    54  
    55    TempPath tmpfs_dir_;
    56    TempPath file_;
    57    std::string filename_;
    58  };
    59  
    60  TEST_F(GetDentsTest, GetDents) {
    61    std::string verity_dir =
    62        ASSERT_NO_ERRNO_AND_VALUE(MountVerity(tmpfs_dir_.path(), filename_));
    63  
    64    std::vector<std::string> expect = {".", "..", filename_};
    65    EXPECT_NO_ERRNO(DirContains(verity_dir, expect, /*exclude=*/{}));
    66  }
    67  
    68  TEST_F(GetDentsTest, Deleted) {
    69    std::string verity_dir =
    70        ASSERT_NO_ERRNO_AND_VALUE(MountVerity(tmpfs_dir_.path(), filename_));
    71  
    72    EXPECT_THAT(unlink(JoinPath(tmpfs_dir_.path(), filename_).c_str()),
    73                SyscallSucceeds());
    74  
    75    EXPECT_THAT(DirContains(verity_dir, /*expect=*/{}, /*exclude=*/{}),
    76                PosixErrorIs(EIO, ::testing::_));
    77  }
    78  
    79  TEST_F(GetDentsTest, Renamed) {
    80    std::string verity_dir =
    81        ASSERT_NO_ERRNO_AND_VALUE(MountVerity(tmpfs_dir_.path(), filename_));
    82  
    83    std::string new_file_name = "renamed-" + filename_;
    84    EXPECT_THAT(rename(JoinPath(tmpfs_dir_.path(), filename_).c_str(),
    85                       JoinPath(tmpfs_dir_.path(), new_file_name).c_str()),
    86                SyscallSucceeds());
    87  
    88    EXPECT_THAT(DirContains(verity_dir, /*expect=*/{}, /*exclude=*/{}),
    89                PosixErrorIs(EIO, ::testing::_));
    90  }
    91  
    92  }  // namespace
    93  
    94  }  // namespace testing
    95  }  // namespace gvisor