x86/x86asm: fix panic on truncated VEX/EVEX prefix decodeAVX guards every read from src except the opcode byte itself, so a stream ending exactly at the end of a VEX or EVEX prefix indexes out of range instead of reporting a truncated instruction: c5 fc panic: index out of range [2] with length 2 c4 e2 7d panic: index out of range [3] with length 3 62 f1 7c 48 panic: index out of range [4] with length 4 Add the missing bounds check and extend TestDecodeDoesNotCrash with the three prefix forms. Fixes golang/go#81447. Change-Id: Id68526e432646ea95d2c1b84d715444ad2d4fb9a GitHub-Last-Rev: 2a9c2bcbcd58bf223e12b76e9821baf50829dff8 GitHub-Pull-Request: golang/arch#25 Reviewed-on: https://go-review.googlesource.com/c/arch/+/830644 Reviewed-by: Keith Randall <khr@golang.org> Reviewed-by: Cherry Mui <cherryyz@google.com> LUCI-TryBot-Result: golang-scoped@luci-project-accounts.iam.gserviceaccount.com <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Auto-Submit: Keith Randall <khr@golang.org> Reviewed-by: Keith Randall <khr@google.com>
diff --git a/x86/x86asm/avx.go b/x86/x86asm/avx.go index 148f72b..82c3472 100644 --- a/x86/x86asm/avx.go +++ b/x86/x86asm/avx.go
@@ -76,6 +76,9 @@ _ = evex_z // TODO: use zeroing mask if needed for output + if pos >= len(src) { + return inst, errors.New("truncated") + } opbyte := src[pos] pos++
diff --git a/x86/x86asm/decode_test.go b/x86/x86asm/decode_test.go index 4543cd2..e409a2f 100644 --- a/x86/x86asm/decode_test.go +++ b/x86/x86asm/decode_test.go
@@ -75,6 +75,11 @@ []byte{}, []byte{0xc5}, []byte{0xc4}, + // Streams ending exactly at the end of a VEX or EVEX prefix, + // leaving no opcode byte. + []byte{0xc5, 0xfc}, + []byte{0xc4, 0xe2, 0x7d}, + []byte{0x62, 0xf1, 0x7c, 0x48}, } for _, test := range cases { _, err := Decode([]byte(test), 64) // the only goal is that this line does not panic