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