aboutsummaryrefslogtreecommitdiffstats
path: root/pkg/ifuzz
diff options
context:
space:
mode:
authorAlexander Potapenko <glider@google.com>2024-04-30 15:05:03 +0200
committerAlexander Potapenko <glider@google.com>2024-04-30 13:24:04 +0000
commita9099be4f9494bbd31b891863568f661ddd9c509 (patch)
treebaf3ef2a202ef92c4f6076b994c906e8c6efca67 /pkg/ifuzz
parent528d487f9857a005ddf12721ab7a2b1c8d22b515 (diff)
pkg/ifuzz: fix instruction decoding on x86
Decode() was only checking full opcode byte(s), whereas certain instructions are encoded in a way that some bits of the opcode are stored in the ModR/M byte. In particular, e.g. there is a variation of MUL encoded as: F7 /4 (which means the opcode byte is F7, and MODRM.reg is 4), and a variation of TEST encoded as: F7 /0 (opcode byte is also F7, and MODRM.reg is 0), which were previously indistinguishable (the decoder would incorrectly treat the MUL instruction as a TEST instruction if there were at least four extra bytes following it). Make sure to calculate and check the MODRM.reg value if insn.Reg is set to a non-negative value.
Diffstat (limited to 'pkg/ifuzz')
-rw-r--r--pkg/ifuzz/x86/decode.go4
1 files changed, 4 insertions, 0 deletions
diff --git a/pkg/ifuzz/x86/decode.go b/pkg/ifuzz/x86/decode.go
index 1306f40db..0160e0fd3 100644
--- a/pkg/ifuzz/x86/decode.go
+++ b/pkg/ifuzz/x86/decode.go
@@ -145,7 +145,11 @@ nextInsn:
modrm := text1[0]
text1 = text1[1:]
mod := modrm >> 6
+ reg := int8(modrm>>3) & 7
rm := modrm & 7
+ if insn.Reg >= 0 && reg != insn.Reg {
+ continue nextInsn
+ }
if !insn.NoSibDisp {
disp := 0
if addrSize == 2 {