github.com/SagerNet/gvisor@v0.0.0-20210707092255-7731c139d75c/test/syscalls/linux/time.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 <time.h>
    17  
    18  #include "gtest/gtest.h"
    19  #include "test/util/proc_util.h"
    20  #include "test/util/test_util.h"
    21  
    22  namespace gvisor {
    23  namespace testing {
    24  
    25  namespace {
    26  
    27  constexpr long kFudgeSeconds = 5;
    28  
    29  #if defined(__x86_64__) || defined(__i386__)
    30  // Mimics the time(2) wrapper from glibc prior to 2.15.
    31  time_t vsyscall_time(time_t* t) {
    32    constexpr uint64_t kVsyscallTimeEntry = 0xffffffffff600400;
    33    return reinterpret_cast<time_t (*)(time_t*)>(kVsyscallTimeEntry)(t);
    34  }
    35  
    36  TEST(TimeTest, VsyscallTime_Succeeds) {
    37    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(IsVsyscallEnabled()));
    38  
    39    time_t t1, t2;
    40  
    41    {
    42      const DisableSave ds;  // Timing assertions.
    43      EXPECT_THAT(time(&t1), SyscallSucceeds());
    44      EXPECT_THAT(vsyscall_time(&t2), SyscallSucceeds());
    45    }
    46  
    47    // Time should be monotonic.
    48    EXPECT_LE(static_cast<long>(t1), static_cast<long>(t2));
    49  
    50    // Check that it's within kFudge seconds.
    51    EXPECT_LE(static_cast<long>(t2), static_cast<long>(t1) + kFudgeSeconds);
    52  
    53    // Redo with save.
    54    EXPECT_THAT(time(&t1), SyscallSucceeds());
    55    EXPECT_THAT(vsyscall_time(&t2), SyscallSucceeds());
    56  
    57    // Time should be monotonic.
    58    EXPECT_LE(static_cast<long>(t1), static_cast<long>(t2));
    59  }
    60  
    61  TEST(TimeTest, VsyscallTime_InvalidAddressSIGSEGV) {
    62    EXPECT_EXIT(vsyscall_time(reinterpret_cast<time_t*>(0x1)),
    63                ::testing::KilledBySignal(SIGSEGV), "");
    64  }
    65  
    66  // Mimics the gettimeofday(2) wrapper from the Go runtime <= 1.2.
    67  int vsyscall_gettimeofday(struct timeval* tv, struct timezone* tz) {
    68    constexpr uint64_t kVsyscallGettimeofdayEntry = 0xffffffffff600000;
    69    return reinterpret_cast<int (*)(struct timeval*, struct timezone*)>(
    70        kVsyscallGettimeofdayEntry)(tv, tz);
    71  }
    72  
    73  TEST(TimeTest, VsyscallGettimeofday_Succeeds) {
    74    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(IsVsyscallEnabled()));
    75  
    76    struct timeval tv1, tv2;
    77    struct timezone tz1, tz2;
    78  
    79    {
    80      const DisableSave ds;  // Timing assertions.
    81      EXPECT_THAT(gettimeofday(&tv1, &tz1), SyscallSucceeds());
    82      EXPECT_THAT(vsyscall_gettimeofday(&tv2, &tz2), SyscallSucceeds());
    83    }
    84  
    85    // See above.
    86    EXPECT_LE(static_cast<long>(tv1.tv_sec), static_cast<long>(tv2.tv_sec));
    87    EXPECT_LE(static_cast<long>(tv2.tv_sec),
    88              static_cast<long>(tv1.tv_sec) + kFudgeSeconds);
    89  
    90    // Redo with save.
    91    EXPECT_THAT(gettimeofday(&tv1, &tz1), SyscallSucceeds());
    92    EXPECT_THAT(vsyscall_gettimeofday(&tv2, &tz2), SyscallSucceeds());
    93  }
    94  
    95  TEST(TimeTest, VsyscallGettimeofday_InvalidAddressSIGSEGV) {
    96    SKIP_IF(!ASSERT_NO_ERRNO_AND_VALUE(IsVsyscallEnabled()));
    97  
    98    EXPECT_EXIT(vsyscall_gettimeofday(reinterpret_cast<struct timeval*>(0x1),
    99                                      reinterpret_cast<struct timezone*>(0x1)),
   100                ::testing::KilledBySignal(SIGSEGV), "");
   101  }
   102  #endif
   103  
   104  }  // namespace
   105  
   106  }  // namespace testing
   107  }  // namespace gvisor