aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/IR/Module.cpp
diff options
context:
space:
mode:
authorAlexey Samsonov <vonosmas@gmail.com>2014-09-08 19:16:28 +0000
committerAlexey Samsonov <vonosmas@gmail.com>2014-09-08 19:16:28 +0000
commitaf023adb86d326f7efeebbbbf28d659e7f73b94f (patch)
tree9123f3a575f5cae7993d4b490a64bb4df4d1afee /llvm/lib/IR/Module.cpp
parent82944983b4aca8389441f3a1aadce51ff572759d (diff)
downloadllvm-af023adb86d326f7efeebbbbf28d659e7f73b94f.zip
llvm-af023adb86d326f7efeebbbbf28d659e7f73b94f.tar.gz
llvm-af023adb86d326f7efeebbbbf28d659e7f73b94f.tar.bz2
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
Diffstat (limited to 'llvm/lib/IR/Module.cpp')
-rw-r--r--llvm/lib/IR/Module.cpp19
1 files changed, 15 insertions, 4 deletions
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<ConstantInt>(V)) {
+ uint64_t Val = Behavior->getLimitedValue();
+ if (Val >= ModFlagBehaviorFirstVal && Val <= ModFlagBehaviorLastVal) {
+ MFB = static_cast<ModFlagBehavior>(Val);
+ return true;
+ }
+ }
+ return false;
+}
+
/// getModuleFlagsMetadata - Returns the module flags in the provided vector.
void Module::
getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
@@ -266,15 +277,15 @@ getModuleFlagsMetadata(SmallVectorImpl<ModuleFlagEntry> &Flags) const {
if (!ModFlags) return;
for (const MDNode *Flag : ModFlags->operands()) {
- if (Flag->getNumOperands() >= 3 && isa<ConstantInt>(Flag->getOperand(0)) &&
+ ModFlagBehavior MFB;
+ if (Flag->getNumOperands() >= 3 &&
+ isValidModFlagBehavior(Flag->getOperand(0), MFB) &&
isa<MDString>(Flag->getOperand(1))) {
// Check the operands of the MDNode before accessing the operands.
// The verifier will actually catch these failures.
- ConstantInt *Behavior = cast<ConstantInt>(Flag->getOperand(0));
MDString *Key = cast<MDString>(Flag->getOperand(1));
Value *Val = Flag->getOperand(2);
- Flags.push_back(ModuleFlagEntry(ModFlagBehavior(Behavior->getZExtValue()),
- Key, Val));
+ Flags.push_back(ModuleFlagEntry(MFB, Key, Val));
}
}
}