]> Cypherpunks repositories - gostls13.git/commitdiff
runtime: don't crash if vsyscall and vdso are disabled on x86_64
authorAndrei Vagin <avagin@google.com>
Tue, 29 Sep 2020 04:45:55 +0000 (04:45 +0000)
committerIan Lance Taylor <iant@golang.org>
Wed, 30 Sep 2020 05:39:59 +0000 (05:39 +0000)
If vdso is disabled, the goruntime calls gettimeofday from vsyscall,
but if vsyscall is disabled too, all golang binaries crash:

SIGSEGV {si_signo=SIGSEGV, si_code=SEGV_MAPERR, si_addr=0xffffffffff600000} ---
killed by SIGSEGV (core dumped) ++

vsyscall doesn't work as it was designed for a long time due to security
reasons and now vsyscall is a little more expensive than real syscalls:
https://github.com/torvalds/linux/commit/5cec93c216db

This patch reworks the code to call syscalls if the vdso library isn't
available.

Change-Id: I16cbf3f49871bea91e26af1f49aa0ae2fbd3a01d
GitHub-Last-Rev: 1d133cd30a5dee1fea9aee0fb4ea0b07e0e87f2a
GitHub-Pull-Request: golang/go#41681
Reviewed-on: https://go-review.googlesource.com/c/go/+/257982
Run-TryBot: Tobias Klauser <tobias.klauser@gmail.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Reviewed-by: Michael Pratt <mpratt@google.com>
Trust: Michael Pratt <mpratt@google.com>

src/runtime/sys_linux_amd64.s
src/runtime/vdso_linux_amd64.go
src/syscall/asm_linux_amd64.s

index 8d90813589198328184e7869cc1220a1ab5d80c6..681cd2027478c318797350a2f80a18689af6c197 100644 (file)
@@ -40,6 +40,7 @@
 #define SYS_futex              202
 #define SYS_sched_getaffinity  204
 #define SYS_epoll_create       213
+#define SYS_clock_gettime      228
 #define SYS_exit_group         231
 #define SYS_epoll_ctl          233
 #define SYS_tgkill             234
@@ -241,15 +242,15 @@ noswitch:
        SUBQ    $16, SP         // Space for results
        ANDQ    $~15, SP        // Align for C code
 
+       MOVL    $0, DI // CLOCK_REALTIME
+       LEAQ    0(SP), SI
        MOVQ    runtime·vdsoClockgettimeSym(SB), AX
        CMPQ    AX, $0
        JEQ     fallback
-       MOVL    $0, DI // CLOCK_REALTIME
-       LEAQ    0(SP), SI
        CALL    AX
+ret:
        MOVQ    0(SP), AX       // sec
        MOVQ    8(SP), DX       // nsec
-ret:
        MOVQ    R12, SP         // Restore real SP
        // Restore vdsoPC, vdsoSP
        // We don't worry about being signaled between the two stores.
@@ -264,13 +265,8 @@ ret:
        MOVL    DX, nsec+8(FP)
        RET
 fallback:
-       LEAQ    0(SP), DI
-       MOVQ    $0, SI
-       MOVQ    runtime·vdsoGettimeofdaySym(SB), AX
-       CALL    AX
-       MOVQ    0(SP), AX       // sec
-       MOVL    8(SP), DX       // usec
-       IMULQ   $1000, DX
+       MOVQ    $SYS_clock_gettime, AX
+       SYSCALL
        JMP ret
 
 // func nanotime1() int64
@@ -306,15 +302,15 @@ noswitch:
        SUBQ    $16, SP         // Space for results
        ANDQ    $~15, SP        // Align for C code
 
+       MOVL    $1, DI // CLOCK_MONOTONIC
+       LEAQ    0(SP), SI
        MOVQ    runtime·vdsoClockgettimeSym(SB), AX
        CMPQ    AX, $0
        JEQ     fallback
-       MOVL    $1, DI // CLOCK_MONOTONIC
-       LEAQ    0(SP), SI
        CALL    AX
+ret:
        MOVQ    0(SP), AX       // sec
        MOVQ    8(SP), DX       // nsec
-ret:
        MOVQ    R12, SP         // Restore real SP
        // Restore vdsoPC, vdsoSP
        // We don't worry about being signaled between the two stores.
@@ -332,13 +328,8 @@ ret:
        MOVQ    AX, ret+0(FP)
        RET
 fallback:
-       LEAQ    0(SP), DI
-       MOVQ    $0, SI
-       MOVQ    runtime·vdsoGettimeofdaySym(SB), AX
-       CALL    AX
-       MOVQ    0(SP), AX       // sec
-       MOVL    8(SP), DX       // usec
-       IMULQ   $1000, DX
+       MOVQ    $SYS_clock_gettime, AX
+       SYSCALL
        JMP     ret
 
 TEXT runtime·rtsigprocmask(SB),NOSPLIT,$0-28
index d9ab4ab3c67f4538a590ee262df6f0c9a58aa14a..4e9f748f4a1a71c66b84455d740a1c7177b986c8 100644 (file)
@@ -17,8 +17,7 @@ var vdsoSymbolKeys = []vdsoSymbolKey{
        {"__vdso_clock_gettime", 0xd35ec75, 0x6e43a318, &vdsoClockgettimeSym},
 }
 
-// initialize with vsyscall fallbacks
 var (
-       vdsoGettimeofdaySym uintptr = 0xffffffffff600000
-       vdsoClockgettimeSym uintptr = 0
+       vdsoGettimeofdaySym uintptr
+       vdsoClockgettimeSym uintptr
 )
index 2c3374338f170b2d4f43ccb991494a73289f7532..ba22179dc2ed4099353d1d2c3b6eb318284a23fa 100644 (file)
@@ -9,6 +9,8 @@
 // System calls for AMD64, Linux
 //
 
+#define SYS_gettimeofday 96
+
 // func Syscall(trap int64, a1, a2, a3 uintptr) (r1, r2, err uintptr);
 // Trap # in AX, args in DI SI DX R10 R8 R9, return in AX DX
 // Note that this differs from "standard" ABI convention, which
@@ -144,13 +146,19 @@ TEXT ·gettimeofday(SB),NOSPLIT,$0-16
        MOVQ    tv+0(FP), DI
        MOVQ    $0, SI
        MOVQ    runtime·vdsoGettimeofdaySym(SB), AX
+       TESTQ   AX, AX
+       JZ fallback
        CALL    AX
-
+ret:
        CMPQ    AX, $0xfffffffffffff001
        JLS     ok7
        NEGQ    AX
        MOVQ    AX, err+8(FP)
        RET
+fallback:
+       MOVL    $SYS_gettimeofday, AX
+       SYSCALL
+       JMP ret
 ok7:
        MOVQ    $0, err+8(FP)
        RET