gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/fuse.cc (about)

     1  // Copyright 2023 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 <linux/capability.h>
    17  #include <stdio.h>
    18  #include <sys/mount.h>
    19  #include <sys/stat.h>
    20  #include <unistd.h>
    21  
    22  #include <cerrno>
    23  #include <cstdint>
    24  #include <cstdlib>
    25  #include <string>
    26  #include <vector>
    27  
    28  #include "gmock/gmock.h"
    29  #include "gtest/gtest.h"
    30  #include "absl/strings/str_format.h"
    31  #include "absl/strings/string_view.h"
    32  #include "test/util/file_descriptor.h"
    33  #include "test/util/fs_util.h"
    34  #include "test/util/linux_capability_util.h"
    35  #include "test/util/posix_error.h"
    36  #include "test/util/temp_path.h"
    37  #include "test/util/test_util.h"
    38  
    39  namespace gvisor {
    40  namespace testing {
    41  
    42  namespace {
    43  
    44  TEST(FuseTest, RejectBadInit) {
    45    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
    46    const FileDescriptor fd =
    47        ASSERT_NO_ERRNO_AND_VALUE(Open("/dev/fuse", O_RDWR, 0));
    48  
    49    auto mount_point = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateDir());
    50    auto mount_opts =
    51        absl::StrFormat("fd=%d,user_id=0,group_id=0,rootmode=40000", fd.get());
    52  
    53    EXPECT_THAT(mount("fuse", mount_point.path().c_str(), "fuse",
    54                      MS_NODEV | MS_NOSUID, mount_opts.c_str()),
    55                SyscallSucceeds());
    56    mount_point.release();
    57  
    58    struct response {
    59      uint32_t len;
    60      int32_t err;
    61      uint64_t uid;
    62    } resp;
    63    // min value for length is 24 + sizeof(response)
    64    resp.len = 24 + sizeof(resp) - 1;
    65    resp.err = 0;
    66    resp.uid = 2;
    67  
    68    ASSERT_THAT(write(fd.get(), reinterpret_cast<char*>(&resp), sizeof(resp)),
    69                SyscallFailsWithErrno(EINVAL));
    70  }
    71  
    72  TEST(FuseTest, LookupUpdatesInode) {
    73    SKIP_IF(absl::NullSafeStringView(getenv("GVISOR_FUSE_TEST")) != "TRUE");
    74    const std::string kFileData = "May thy knife chip and shatter.\n";
    75    TempPath path = ASSERT_NO_ERRNO_AND_VALUE(TempPath::CreateFileWith(
    76        GetAbsoluteTestTmpdir(), kFileData, TempPath::kDefaultFileMode));
    77  
    78    FileDescriptor fd = ASSERT_NO_ERRNO_AND_VALUE(Open(path.path(), O_RDONLY));
    79    std::vector<char> buf(kFileData.size());
    80    ASSERT_THAT(ReadFd(fd.get(), buf.data(), kFileData.size()),
    81                SyscallSucceedsWithValue(kFileData.size()));
    82  
    83    ASSERT_THAT(unlink(JoinPath("/fuse", Basename(path.path())).c_str()),
    84                SyscallSucceeds());
    85  
    86    EXPECT_THAT(access(path.path().c_str(), O_RDONLY),
    87                SyscallFailsWithErrno(ENOENT));
    88  }
    89  
    90  }  // namespace
    91  }  // namespace testing
    92  }  // namespace gvisor