From af023adb86d326f7efeebbbbf28d659e7f73b94f Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Mon, 8 Sep 2014 19:16:28 +0000 Subject: Be more careful in parsing Module::ModFlagBehavior value to make sure we don't do invalid load of an enum. Share the conversion code between llvm::Module implementation and the verifier. This bug was reported by UBSan. llvm-svn: 217395 --- llvm/lib/IR/Module.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'llvm/lib/IR/Module.cpp') diff --git a/llvm/lib/IR/Module.cpp b/llvm/lib/IR/Module.cpp index 98e4706..7f673d0 100644 --- a/llvm/lib/IR/Module.cpp +++ b/llvm/lib/IR/Module.cpp @@ -259,6 +259,17 @@ void Module::eraseNamedMetadata(NamedMDNode *NMD) { NamedMDList.erase(NMD); } +bool Module::isValidModFlagBehavior(Value *V, ModFlagBehavior &MFB) { + if (ConstantInt *Behavior = dyn_cast(V)) { + uint64_t Val = Behavior->getLimitedValue(); + if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) { + MFB = static_cast(Val); + return true; + } + } + return false; +} + /// getModuleFlagsMetadata - Returns the module flags in the provided vector. void Module:: getModuleFlagsMetadata(SmallVectorImpl &Flags) const { @@ -266,15 +277,15 @@ getModuleFlagsMetadata(SmallVectorImpl &Flags) const { if (!ModFlags) return; for (const MDNode *Flag : ModFlags->operands()) { - if (Flag->getNumOperands() >= 3 && isa(Flag->getOperand(0)) && + ModFlagBehavior MFB; + if (Flag->getNumOperands() >= 3 && + isValidModFlagBehavior(Flag->getOperand(0), MFB) && isa(Flag->getOperand(1))) { // Check the operands of the MDNode before accessing the operands. // The verifier will actually catch these failures. - ConstantInt *Behavior = cast(Flag->getOperand(0)); MDString *Key = cast(Flag->getOperand(1)); Value *Val = Flag->getOperand(2); - Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()), - Key, Val)); + Flags.push_back(ModuleFlagEntry(MFB, Key, Val)); } } } -- cgit v1.1