-
Notifications
You must be signed in to change notification settings - Fork 17.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/sys/cpu: SIGILL on arm64 in readARM64Registers #57336
Comments
Apparently that Realtek RTD1296 CPU is:
|
(attn @golang/arm) |
The instruction is |
I think |
Looks like it's:
|
FWIW, on Synology, this program runs as non-root but with some additional capabilities (as in |
Looks like this is the same CPU across: https://www.synology.com/en-us/products/DS220j#specs ... which are the 5 of the top 6 arm64 Synology models per our stats. (the DS120j has a Marvell Armada 3700 88F3720) |
It looks like these instructions do trap. Linux emulates the instructions and returns to userspace: https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=77c97b4ee21290f5f083173d957843b615abbff2 It looks like emulation support was added in Linux 4.11, so it makes sense that 4.4 is crashing. From the patch, it seems that we should check for |
Out of curiosity, I checked: no Synology model (for any architecture) runs a kernel newer than 4.4.x. Top kernel versions on Synology we see used:
But who knows how much was cherry-picked into those |
So in this case I guess the func doinit() {
if err := readHWCAP(); err != nil {
// failed to read /proc/self/auxv, try reading registers directly
readARM64Registers()
return
}
... But these same hwcap flags are available in
Should we try parsing that first as another fallback before the Or would y'all prefer looking at the kernel version and hope that's indicative of reality? |
Related issue with x/sys/cpu on arm64 but on OpenBSD is #42517 |
@lovitus notes in tailscale/tailscale#5793 (comment) that they're able to cat
|
I am fairly surprised that Is tailscale running inside of some kind of sandbox? Running under `strace -f`` could at least give a sense of what kind of error we get trying to open/read auxv. |
(As an aside, I'm sad we can't just get auxv from runtime main. It shouldn't be necessary to open a file to read auxv...) |
As far as changing x/sys/cpu to avoid SIGILL when
|
@tklauser For more context, I'm curious what your motivation for https://go.dev/cl/209478 was. What systems did not have |
Synology has two major OS versions in the wild. In the newer one (DSM7), packages run non-root but can request certain capabilities(7) in their manifest. I'd never noticed a filesystem chroot or anything but our existing four Synology test devices don't yet include arm64. One is arriving Monday, though, and then I'll be able to see. Checking uname kernel version seems easiest. We do that already elsewhere so should work. |
x/sys/cpu already reaches into the standard library for a couple of cases. We could save the auxv information in |
Change https://go.dev/cl/458256 mentions this issue: |
Something like this? https://go-review.googlesource.com/c/go/+/458256 I then made a change to x/sys/cpu using that. Seems to work. |
Amazon arrived and I have yet another test device so I can reproduce now.
If I remove those capabilities, then x/sys/cpu reads /proc/self/auxv and is fine. (but runs in a degraded mode where certain operations aren't permitted due to the Synology sandbox) |
Minimal repro against Linux 4.4.180+ (arm64): bradfitz@tsdev:~/src/golang.org/x/sys$ git di
diff --git a/cpu/cpu_linux_arm64.go b/cpu/cpu_linux_arm64.go
index 79a38a0..fee6f12 100644
--- a/cpu/cpu_linux_arm64.go
+++ b/cpu/cpu_linux_arm64.go
@@ -4,6 +4,11 @@
package cpu
+import (
+ "io/ioutil"
+ "log"
+)
+
// HWCAP/HWCAP2 bits. These are exposed by Linux.
const (
hwcap_FP = 1 << 0
@@ -34,6 +39,9 @@ const (
func doinit() {
if err := readHWCAP(); err != nil {
+ log.Printf("XXX readHWCap error: %v", err)
+ cpuinfo, err := ioutil.ReadFile("/proc/cpuinfo")
+ log.Printf("XXX /proc/cpuinfo = %q, %v", cpuinfo, err)
// failed to read /proc/self/auxv, try reading registers directly
readARM64Registers()
return Then, after a go.mod replace:
@prattmic wrote:
Neither did I, but it seems to work. I'll send a change to fall back to parsing that for now for Linux kernels prior to 4.11. |
Change https://go.dev/cl/458315 mentions this issue: |
Updates #57336 Change-Id: I181885f59bac59360b855d3990326ea2b268bd28 Reviewed-on: https://go-review.googlesource.com/c/go/+/458256 Reviewed-by: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Change https://go.dev/cl/465295 mentions this issue: |
Depends on https://go.dev/cl/458256 This change only does Linux for now. Updates golang/go#57336 Change-Id: I0659697c1bdc6e2577c6251b964a0df32047ee12 Reviewed-on: https://go-review.googlesource.com/c/sys/+/465295 Reviewed-by: Ian Lance Taylor <iant@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Reviewed-by: Michael Pratt <mpratt@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Updates golang#57336 Change-Id: I181885f59bac59360b855d3990326ea2b268bd28 Reviewed-on: https://go-review.googlesource.com/c/go/+/458256 Reviewed-by: Michael Pratt <mpratt@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Auto-Submit: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Austin Clements <austin@google.com> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
On a Synology DS220J (Realtek RTD1296), an arm64 CPU, with
x/sys@v0.1.0
:(originally reported in tailscale/tailscale#5793)
Although that's for x/sys v0.1, there have been no cpu changes since:
@tklauser, looks like you touched that code last in 85b82a3
/cc @golang/runtime
The text was updated successfully, but these errors were encountered: