1// Copyright 2019 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build linux
6// +build 386 amd64
7
8package runtime
9
10//go:noescape
11func uname(utsname *new_utsname) int
12
13func mlock(addr, len uintptr) int
14
15func osArchInit() {
16	// Linux 5.2 introduced a bug that can corrupt vector
17	// registers on return from a signal if the signal stack isn't
18	// faulted in:
19	// https://bugzilla.kernel.org/show_bug.cgi?id=205663
20	//
21	// It was fixed in 5.3.15, 5.4.2, and all 5.5 and later
22	// kernels.
23	//
24	// If we're on an affected kernel, work around this issue by
25	// mlocking the top page of every signal stack. This doesn't
26	// help for signal stacks created in C, but there's not much
27	// we can do about that.
28	//
29	// TODO(austin): Remove this in Go 1.15, at which point it
30	// will be unlikely to encounter any of the affected kernels
31	// in the wild.
32
33	var uts new_utsname
34	if uname(&uts) < 0 {
35		throw("uname failed")
36	}
37	// Check for null terminator to ensure gostringnocopy doesn't
38	// walk off the end of the release string.
39	found := false
40	for _, b := range uts.release {
41		if b == 0 {
42			found = true
43			break
44		}
45	}
46	if !found {
47		return
48	}
49	rel := gostringnocopy(&uts.release[0])
50
51	major, minor, patch, ok := parseRelease(rel)
52	if !ok {
53		return
54	}
55
56	if major == 5 && (minor == 2 || minor == 3 && patch < 15 || minor == 4 && patch < 2) {
57		gsignalInitQuirk = mlockGsignal
58		if m0.gsignal != nil {
59			throw("gsignal quirk too late")
60		}
61	}
62}
63
64func mlockGsignal(gsignal *g) {
65	if err := mlock(gsignal.stack.hi-physPageSize, physPageSize); err < 0 {
66		printlock()
67		println("runtime: mlock of signal stack failed:", -err)
68		if err == -_ENOMEM {
69			println("runtime: increase the mlock limit (ulimit -l) or")
70		}
71		println("runtime: update your kernel to 5.3.15+, 5.4.2+, or 5.5+")
72		throw("mlock failed")
73	}
74}
75