Repository: go
Issue: x/crypto: curve25519.ladderstep runs into segmentation fault when invoked under emulation of qemu-x86_64 on an ARMv6 host
Labels: NeedsInvestigation,arch-arm

### What version of Go are you using (`go version`)?
On the compiler host:
<pre>
$ go version
go version go1.16 linux/amd64
</pre>

### Does this issue reproduce with the latest release?
Yes

### What operating system and processor architecture are you using (`go env`)?
The compiler runs on linux/amd64, target host is linux/arm, emulator on the target host is qemu-x86_64.

### What did you do?
Compile the following code with `env CGO_ENABLED=0 go build -o main-go16 ./main.go`:

<pre>
package main

import (
        "crypto/tls"
        "log"
)

func main() {
        _, err := tls.Dial("tcp", "google.com:443", &tls.Config{InsecureSkipVerify: true})
        if err != nil {
                log.Panic(err)
        }
}
</pre>

Then copy the compiled program (which is an x86-64 ELF executable) onto an ARMv6 host (Raspberry Pi Zero W), and run it using QEMU:

<pre>
howard@hzgl-rpi ~> cat /etc/os-release
PRETTY_NAME="Raspbian GNU/Linux 10 (buster)"
NAME="Raspbian GNU/Linux"
VERSION_ID="10"
VERSION="10 (buster)"
VERSION_CODENAME=buster
ID=raspbian
ID_LIKE=debian
HOME_URL="http://www.raspbian.org/"
SUPPORT_URL="http://www.raspbian.org/RaspbianForums"
BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs

howard@hzgl-rpi ~> dpkg -s qemu-user
Package: qemu-user
...
Maintainer: Debian QEMU Team <pkg-qemu-devel@lists.alioth.debian.org>
Architecture: armhf
Multi-Arch: foreign
Source: qemu
Version: 1:3.1+dfsg-8+deb10u8
...

howard@hzgl-rpi ~> qemu-x86_64 ./main-go16
unexpected fault address 0xe58d209c
fatal error: fault
[signal SIGSEGV: segmentation violation code=0x1 addr=0xe58d209c pc=0x5794fd]

goroutine 1 [running]:
runtime.throw(0x607d62, 0x5)
        /root/sdk/go1.16/src/runtime/panic.go:1117 +0x72 fp=0x9003f478 sp=0x9003f448 pc=0x435512
runtime.sigpanic()
        /root/sdk/go1.16/src/runtime/signal_unix.go:741 +0x268 fp=0x9003f4b0 sp=0x9003f478 pc=0x44bb08
vendor/golang.org/x/crypto/curve25519.ladderstep(0x9003f610)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.s:101 +0x5d fp=0x9003f5e8 sp=0x9003f4b0 pc=0x5794fd
vendor/golang.org/x/crypto/curve25519.mladder(0x9003f748, 0x9003f720, 0x9003f700)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go:52 +0x136 fp=0x9003f6e8 sp=0x9003f5e8 pc=0x5788d6
vendor/golang.org/x/crypto/curve25519.scalarMult(0x900182c0, 0x9003f7d8, 0x71f3a0)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519_amd64.go:71 +0xe7 fp=0x9003f780 sp=0x9003f6e8 pc=0x578a67
vendor/golang.org/x/crypto/curve25519.ScalarMult(...)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519.go:21
vendor/golang.org/x/crypto/curve25519.ScalarBaseMult(...)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519.go:30
vendor/golang.org/x/crypto/curve25519.x25519(0x900182c0, 0x900182a0, 0x20, 0x20, 0x71f3a0, 0x20, 0x20, 0x0, 0x0, 0x9003f8f8, ...)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519.go:85 +0x22d fp=0x9003f848 sp=0x9003f780 pc=0x5785ed
vendor/golang.org/x/crypto/curve25519.X25519(...)
        /root/sdk/go1.16/src/vendor/golang.org/x/crypto/curve25519/curve25519.go:71
crypto/tls.generateECDHEParameters(0x645e20, 0x9005e180, 0x1d, 0x0, 0x13, 0x90020140, 0x10)
        /root/sdk/go1.16/src/crypto/tls/key_schedule.go:118 +0x153 fp=0x9003f908 sp=0x9003f848 pc=0x5a0353
crypto/tls.(*Conn).makeClientHello(0x90064e00, 0x0, 0x9003f9d0, 0x532325, 0x0, 0x0)
        /root/sdk/go1.16/src/crypto/tls/handshake_client.go:127 +0x828 fp=0x9003fa20 sp=0x9003f908 pc=0x588928
crypto/tls.(*Conn).clientHandshake(0x90064e00, 0x0, 0x0)
        /root/sdk/go1.16/src/crypto/tls/handshake_client.go:146 +0x7d fp=0x9003fca8 sp=0x9003fa20 pc=0x5890bd
crypto/tls.(*Conn).clientHandshake-fm(0x40803108, 0x10)
        /root/sdk/go1.16/src/crypto/tls/handshake_client.go:137 +0x33 fp=0x9003fcd0 sp=0x9003fca8 pc=0x5b4a13
crypto/tls.(*Conn).Handshake(0x90064e00, 0x0, 0x0)
        /root/sdk/go1.16/src/crypto/tls/conn.go:1391 +0xc9 fp=0x9003fd40 sp=0x9003fcd0 pc=0x587cc9
crypto/tls.dial(0x648390, 0x90016128, 0x9003feb8, 0x607acc, 0x3, 0x609b00, 0xe, 0x90000f00, 0x0, 0x0, ...)
        /root/sdk/go1.16/src/crypto/tls/tls.go:169 +0x59c fp=0x9003fe60 sp=0x9003fd40 pc=0x5a2efc
crypto/tls.DialWithDialer(...)
        /root/sdk/go1.16/src/crypto/tls/tls.go:115
crypto/tls.Dial(0x607acc, 0x3, 0x609b00, 0xe, 0x90000f00, 0x41a101, 0x0, 0x0)
        /root/sdk/go1.16/src/crypto/tls/tls.go:205 +0xba fp=0x9003ff28 sp=0x9003fe60 pc=0x5a31ba
main.main()
        /root/repro/main.go:9 +0x70 fp=0x9003ff88 sp=0x9003ff28 pc=0x5b72d0
runtime.main()
        /root/sdk/go1.16/src/runtime/proc.go:225 +0x256 fp=0x9003ffe0 sp=0x9003ff88 pc=0x437d56
runtime.goexit()
        /root/sdk/go1.16/src/runtime/asm_amd64.s:1371 +0x1 fp=0x9003ffe8 sp=0x9003ffe0 pc=0x469981
</pre>

I am unsure if it indicates a problem in golang or the qemu emulator.