diff options
| author | Alexander Potapenko <glider@google.com> | 2024-04-30 15:05:03 +0200 |
|---|---|---|
| committer | Alexander Potapenko <glider@google.com> | 2024-04-30 13:24:04 +0000 |
| commit | a9099be4f9494bbd31b891863568f661ddd9c509 (patch) | |
| tree | baf3ef2a202ef92c4f6076b994c906e8c6efca67 /pkg/ifuzz | |
| parent | 528d487f9857a005ddf12721ab7a2b1c8d22b515 (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.go | 4 |
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 { |
