keystone-engine / keystone

Keystone assembler framework: Core (Arm, Arm64, Hexagon, Mips, PowerPC, Sparc, SystemZ & X86) + bindings
http://www.keystone-engine.org
GNU General Public License v2.0
2.3k stars 458 forks source link

An infinite loop in llvm/lib/MC/MCParser/AsmParser.cpp #551

Open solidConf opened 1 year ago

solidConf commented 1 year ago

Description

This vulnerability is of type Loop with an infinite branch. The bug exist in latest stable release (draco-1.5.3) and latest master branch (18569351000cf1b8bd1ea2cc8a02c2e17b76391f, updated on Mar 3, 2022). Specifically, the vulnerable code is located at llvm/lib/MC/MCParser/AsmParser.cpp, line 710-728.

Proof of Concept

Build the latest release version ( or commit 18569351000cf1b8bd1ea2cc8a02c2e17b76391f) and run it using the input poc.zip. Then run it by fuzz_asm_x86_32, fuzz_asm_ppc32be, or fuzz_asm_x86_64.

$: unzip poc.zip
$: cd keystone
$: mkdir build
$: cd build
$: cmake .. 
$: make
$: ./suite/fuzz/fuzz_asm_x86_32 -i poc

This poc is very simple, and the infinite loop can be easily triggered. The bug's basic explanation are highlighted as follows:

while (Lexer.isNot(AsmToken::Eof)) {
    ParseStatementInfo Info;
    if (!parseStatement(Info, nullptr, Address)) {
      count++;
      continue;
    }
    if (!KsError) {
        KsError = Info.KsError;
        return 0;
    }
 }

If the two branches " if (!parseStatement(Info, nullptr, Address)) " and " if (!KsError) " return false, the variables do not change in every iteration in this loop.