From b648ea82f496a7c0dc2d83064618149a7daa3627 Mon Sep 17 00:00:00 2001
From: Nguyen Anh Quynh <aquynh@gmail.com>
Date: Thu, 2 Jun 2016 23:46:01 +0800
Subject: [PATCH] x86: sanity check on Scale of memory operand. this fixes
 issue #154

---
 .../lib/Target/X86/AsmParser/X86AsmParser.cpp | 27 ++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
index 44dc405..a1c46f7 100644
--- a/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
+++ b/llvm/lib/Target/X86/AsmParser/X86AsmParser.cpp
@@ -1263,7 +1263,8 @@ static unsigned getIntelMemOperandSize(StringRef OpStr) {
 std::unique_ptr<X86Operand> X86AsmParser::CreateMemForInlineAsm(
     unsigned SegReg, const MCExpr *Disp, unsigned BaseReg, unsigned IndexReg,
     unsigned Scale, SMLoc Start, SMLoc End, unsigned Size, StringRef Identifier,
-    InlineAsmIdentifierInfo &Info) {
+    InlineAsmIdentifierInfo &Info)
+{
   // If we found a decl other than a VarDecl, then assume it is a FuncDecl or
   // some other label reference.
   if (isa<MCSymbolRefExpr>(Disp) && Info.OpDecl && !Info.IsVarDecl) {
@@ -1588,6 +1589,18 @@ X86AsmParser::ParseIntelBracExpression(unsigned SegReg, SMLoc Start,
   int IndexReg = SM.getIndexReg();
   //printf("--- BaseReg = %u, IndexReg = %u, SegReg = %u\n", BaseReg, IndexReg, SegReg);
   int Scale = SM.getScale();
+  if (IndexReg !=0 && !Scale) {
+      // Scale must go with Index register
+      KsError = KS_ERR_ASM_INVALIDOPERAND;
+      return nullptr;
+  }
+
+  if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
+      // invalid Scale
+      KsError = KS_ERR_ASM_INVALIDOPERAND;
+      return nullptr;
+  }
+
   if (!isParsingInlineAsm()) {
     // handle [-42]
     if (!BaseReg && !IndexReg) {
@@ -2381,6 +2394,18 @@ std::unique_ptr<X86Operand> X86AsmParser::ParseMemOperand(unsigned SegReg,
     return nullptr;
   }
 
+  if (IndexReg !=0 && !Scale) {
+      // Scale must go with Index register
+      KsError = KS_ERR_ASM_INVALIDOPERAND;
+      return nullptr;
+  }
+
+  if (Scale != 1 && Scale != 2 && Scale != 4 && Scale != 8) {
+      // invalid Scale
+      KsError = KS_ERR_ASM_INVALIDOPERAND;
+      return nullptr;
+  }
+
   if (SegReg || BaseReg || IndexReg)
     return X86Operand::CreateMem(getPointerWidth(), SegReg, Disp, BaseReg,
                                  IndexReg, Scale, MemStart, MemEnd);
-- 
GitLab