Skip to content

Commit 3a273a9

Browse files
committed
fixes #32912
The crash occurs when go runtime calls a VDSO function (say __vdso_clock_gettime) and a signal arrives to that thread. Since VDSO functions temporarily destroy the G register (R10), Go functions asynchronously executed in that thread (i.e. Go's signal handler) can try to load data from the destroyed G, which causes segmentation fault.
1 parent 8af02fe commit 3a273a9

File tree

1 file changed

+10
-3
lines changed

1 file changed

+10
-3
lines changed

src/runtime/signal_unix.go

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -289,7 +289,10 @@ func sigtrampgo(sig uint32, info *siginfo, ctx unsafe.Pointer) {
289289
if sigfwdgo(sig, info, ctx) {
290290
return
291291
}
292-
g := getg()
292+
var g *g = nil
293+
if !inVDSOPage(uintptr(info.si_addr)) {
294+
g = getg()
295+
}
293296
if g == nil {
294297
c := &sigctxt{info, ctx}
295298
if sig == _SIGPROF {
@@ -657,8 +660,12 @@ func sigfwdgo(sig uint32, info *siginfo, ctx unsafe.Pointer) bool {
657660
return false
658661
}
659662
// Determine if the signal occurred inside Go code. We test that:
660-
// (1) we were in a goroutine (i.e., m.curg != nil), and
661-
// (2) we weren't in CGO.
663+
// (1) we weren't in VDSO page,
664+
// (2) we were in a goroutine (i.e., m.curg != nil), and
665+
// (3) we weren't in CGO.
666+
if inVDSOPage(uintptr(info.si_addr)) {
667+
return false
668+
}
662669
g := getg()
663670
if g != nil && g.m != nil && g.m.curg != nil && !g.m.incgo {
664671
return false

0 commit comments

Comments
 (0)