Skip to content

Commit

Permalink
runtime: don't crash if vsyscall and vdso are disabled on x86_64
Browse files Browse the repository at this point in the history
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:
torvalds/linux@5cec93c216db

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

Change-Id: I16cbf3f49871bea91e26af1f49aa0ae2fbd3a01d
GitHub-Last-Rev: 1d133cd
GitHub-Pull-Request: golang#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>
  • Loading branch information
avagin authored and ianlancetaylor committed Sep 30, 2020
1 parent 0e85fd7 commit 3caaadd
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 24 deletions.
31 changes: 11 additions & 20 deletions src/runtime/sys_linux_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down Expand Up @@ -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.
Expand All @@ -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
Expand Down
5 changes: 2 additions & 3 deletions src/runtime/vdso_linux_amd64.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
)
10 changes: 9 additions & 1 deletion src/syscall/asm_linux_amd64.s
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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

0 comments on commit 3caaadd

Please sign in to comment.