x86/x86asm: fix three panics on malformed input
All three test cases used to cause a panic.
Change-Id: I2874c1fb6f09e6c3678d0b8d469f2c582dd8f50b
Reviewed-on: https://go-review.googlesource.com/c/155939
Run-TryBot: Josh Bleecher Snyder <josharian@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Reviewed-by: Cherry Zhang <cherryyz@google.com>
diff --git a/x86/x86asm/decode.go b/x86/x86asm/decode.go
index 148870b..250000e 100644
--- a/x86/x86asm/decode.go
+++ b/x86/x86asm/decode.go
@@ -203,7 +203,9 @@
// For now we use instPrefix but perhaps later we will return
// a specific error here.
func truncated(src []byte, mode int) (Inst, error) {
- // return Inst{}, len(src), ErrTruncated
+ if len(src) == 0 {
+ return Inst{}, ErrTruncated
+ }
return instPrefix(src[0], mode) // too long
}
@@ -406,7 +408,7 @@
//Group 5 - Vex encoding
case 0xC5:
- if pos == 0 && (mode == 64 || (mode == 32 && pos+1 < len(src) && src[pos+1]&0xc0 == 0xc0)) {
+ if pos == 0 && pos+1 < len(src) && (mode == 64 || (mode == 32 && src[pos+1]&0xc0 == 0xc0)) {
vex = p
vexIndex = pos
inst.Prefix[pos] = p
@@ -418,7 +420,7 @@
break ReadPrefixes
}
case 0xC4:
- if pos == 0 && (mode == 64 || (mode == 32 && pos+2 < len(src) && src[pos+1]&0xc0 == 0xc0)) {
+ if pos == 0 && pos+2 < len(src) && (mode == 64 || (mode == 32 && src[pos+1]&0xc0 == 0xc0)) {
vex = p
vexIndex = pos
inst.Prefix[pos] = p
diff --git a/x86/x86asm/decode_test.go b/x86/x86asm/decode_test.go
index 127be26..4543cd2 100644
--- a/x86/x86asm/decode_test.go
+++ b/x86/x86asm/decode_test.go
@@ -69,3 +69,17 @@
}
}
}
+
+func TestDecodeDoesNotCrash(t *testing.T) {
+ cases := [...][]byte{
+ []byte{},
+ []byte{0xc5},
+ []byte{0xc4},
+ }
+ for _, test := range cases {
+ _, err := Decode([]byte(test), 64) // the only goal is that this line does not panic
+ if err == nil {
+ t.Errorf("expected error on invalid instruction %x", test)
+ }
+ }
+}