[llvm] 64a93af - [X86][Disassembler] Fix a bug when disassembling an empty string

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Mon Jan 13 10:42:29 PST 2020


Author: Fangrui Song
Date: 2020-01-13T10:42:21-08:00
New Revision: 64a93afc3c630c39e5c583e4f67aef5821d635b6

URL: https://github.com/llvm/llvm-project/commit/64a93afc3c630c39e5c583e4f67aef5821d635b6
DIFF: https://github.com/llvm/llvm-project/commit/64a93afc3c630c39e5c583e4f67aef5821d635b6.diff

LOG: [X86][Disassembler] Fix a bug when disassembling an empty string

readPrefixes() assumes insn->bytes is non-empty. The code path is not
exercised in llvm-mc because llvm-mc does not feed empty input to
MCDisassembler::getInstruction().

This bug is uncovered by a5994c789a2982a770254ae1607b5b4cb641f73c.
An empty string did not crash before because the deleted regionReader()
allowed UINT64_C(-1) as insn->readerCursor.

  Bytes.size() <= Address -> R->Base
  0 <= UINT64_C(-1) - UINT32_C(-1)

Added: 
    

Modified: 
    llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
    llvm/unittests/MC/Disassembler.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
index 8d0c12e94643..34ea95d418bd 100644
--- a/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
+++ b/llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
@@ -203,6 +203,8 @@ static bool isREX(struct InternalInstruction *insn, uint8_t prefix) {
 // Consumes all of an instruction's prefix bytes, and marks the
 // instruction as having them.  Also sets the instruction's default operand,
 // address, and other relevant data sizes to report operands correctly.
+//
+// insn must not be empty.
 static int readPrefixes(struct InternalInstruction *insn) {
   bool isPrefix = true;
   uint8_t byte = 0;
@@ -1707,7 +1709,7 @@ MCDisassembler::DecodeStatus X86GenericDisassembler::getInstruction(
   Insn.readerCursor = Address;
   Insn.mode = fMode;
 
-  if (readPrefixes(&Insn) || readOpcode(&Insn) ||
+  if (Bytes.empty() || readPrefixes(&Insn) || readOpcode(&Insn) ||
       getInstructionID(&Insn, MII.get()) || Insn.instructionID == 0 ||
       readOperands(&Insn)) {
     Size = Insn.readerCursor - Address;

diff  --git a/llvm/unittests/MC/Disassembler.cpp b/llvm/unittests/MC/Disassembler.cpp
index cdb344474ca2..3f9e6e5501e1 100644
--- a/llvm/unittests/MC/Disassembler.cpp
+++ b/llvm/unittests/MC/Disassembler.cpp
@@ -38,6 +38,10 @@ TEST(Disassembler, X86Test) {
   unsigned NumBytes = sizeof(Bytes);
   unsigned PC = 0;
 
+  InstSize =
+      LLVMDisasmInstruction(DCR, BytesP, 0, PC, OutString, OutStringSize);
+  EXPECT_EQ(InstSize, 0U);
+
   InstSize = LLVMDisasmInstruction(DCR, BytesP, NumBytes, PC, OutString,
                                    OutStringSize);
   EXPECT_EQ(InstSize, 1U);


        


More information about the llvm-commits mailing list