gvisor.dev/gvisor@v0.0.0-20240520182842-f9d4d51c7e0f/test/syscalls/linux/setns.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 <sched.h>
    16  
    17  #include <cstdint>
    18  
    19  #include "gmock/gmock.h"
    20  #include "gtest/gtest.h"
    21  #include "test/util/file_descriptor.h"
    22  #include "test/util/linux_capability_util.h"
    23  #include "test/util/posix_error.h"
    24  #include "test/util/test_util.h"
    25  
    26  namespace gvisor {
    27  namespace testing {
    28  namespace {
    29  
    30  TEST(SetnsTest, ChangeIPCNamespace) {
    31    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
    32  
    33    struct stat st;
    34    uint64_t ipcns1, ipcns2, ipcns3;
    35    const FileDescriptor nsfd =
    36        ASSERT_NO_ERRNO_AND_VALUE(Open("/proc/thread-self/ns/ipc", O_RDONLY));
    37    ASSERT_THAT(stat("/proc/thread-self/ns/ipc", &st), SyscallSucceeds());
    38    ipcns1 = st.st_ino;
    39  
    40    // Use unshare(CLONE_NEWIPC) to change into a new IPC namespace.
    41    ASSERT_THAT(unshare(CLONE_NEWIPC), SyscallSucceedsWithValue(0));
    42    ASSERT_THAT(stat("/proc/thread-self/ns/ipc", &st), SyscallSucceeds());
    43    ipcns2 = st.st_ino;
    44    ASSERT_NE(ipcns1, ipcns2);
    45  
    46    ASSERT_THAT(setns(nsfd.get(), CLONE_NEWIPC), SyscallSucceedsWithValue(0));
    47    ASSERT_THAT(stat("/proc/thread-self/ns/ipc", &st), SyscallSucceeds());
    48    ipcns3 = st.st_ino;
    49    EXPECT_EQ(ipcns1, ipcns3);
    50  }
    51  
    52  TEST(SetnsTest, ChangeUTSNamespace) {
    53    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(HaveCapability(CAP_SYS_ADMIN)));
    54  
    55    struct stat st;
    56    uint64_t utsns1, utsns2, utsns3;
    57    const FileDescriptor nsfd =
    58        ASSERT_NO_ERRNO_AND_VALUE(Open("/proc/thread-self/ns/uts", O_RDONLY));
    59    ASSERT_THAT(stat("/proc/thread-self/ns/uts", &st), SyscallSucceeds());
    60    utsns1 = st.st_ino;
    61  
    62    // Use unshare(CLONE_NEWUTS) to change into a new UTS namespace.
    63    ASSERT_THAT(unshare(CLONE_NEWUTS), SyscallSucceedsWithValue(0));
    64    ASSERT_THAT(stat("/proc/thread-self/ns/uts", &st), SyscallSucceeds());
    65    utsns2 = st.st_ino;
    66    ASSERT_NE(utsns1, utsns2);
    67  
    68    ASSERT_THAT(setns(nsfd.get(), CLONE_NEWUTS), SyscallSucceedsWithValue(0));
    69    ASSERT_THAT(stat("/proc/thread-self/ns/uts", &st), SyscallSucceeds());
    70    utsns3 = st.st_ino;
    71    EXPECT_EQ(utsns1, utsns3);
    72  }
    73  
    74  }  // namespace
    75  }  // namespace testing
    76  }  // namespace gvisor