[llvm] b608053 - [IR] Fix replaceUsesWithIf ponetial issue with constants
Stanislav Mekhanoshin via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 28 15:57:31 PDT 2021
Author: Stanislav Mekhanoshin
Date: 2021-06-28T15:55:55-07:00
New Revision: b608053efb88378900d0f08148662e433aa609db
URL: https://github.com/llvm/llvm-project/commit/b608053efb88378900d0f08148662e433aa609db
DIFF: https://github.com/llvm/llvm-project/commit/b608053efb88378900d0f08148662e433aa609db.diff
LOG: [IR] Fix replaceUsesWithIf ponetial issue with constants
There can be a use after free in the Value::replaceUsesWithIf()
if two uses point to the same constant. Patch defers handling
of the constants past the iterator scan.
Another potential issue is that handleOperandChange updates all
the uses in a given Constant, not just the one passed to
ShouldReplace. Added a FIXME comment.
Both issues are not currently exploitable as the only use of
this call with constants avoids it.
Differential Revision: https://reviews.llvm.org/D105061
Added:
Modified:
llvm/lib/IR/Value.cpp
Removed:
################################################################################
diff --git a/llvm/lib/IR/Value.cpp b/llvm/lib/IR/Value.cpp
index c3796f134922..9cb00569598a 100644
--- a/llvm/lib/IR/Value.cpp
+++ b/llvm/lib/IR/Value.cpp
@@ -531,6 +531,9 @@ void Value::replaceUsesWithIf(Value *New,
assert(New->getType() == getType() &&
"replaceUses of value with new value of
diff erent type!");
+ SmallVector<TrackingVH<Constant>, 8> Consts;
+ SmallPtrSet<Constant *, 8> Visited;
+
for (use_iterator UI = use_begin(), E = use_end(); UI != E;) {
Use &U = *UI;
++UI;
@@ -540,12 +543,19 @@ void Value::replaceUsesWithIf(Value *New,
// constant because they are uniqued.
if (auto *C = dyn_cast<Constant>(U.getUser())) {
if (!isa<GlobalValue>(C)) {
- C->handleOperandChange(this, New);
+ if (Visited.insert(C).second)
+ Consts.push_back(TrackingVH<Constant>(C));
continue;
}
}
U.set(New);
}
+
+ while (!Consts.empty()) {
+ // FIXME: handleOperandChange() updates all the uses in a given Constant,
+ // not just the one passed to ShouldReplace
+ Consts.pop_back_val()->handleOperandChange(this, New);
+ }
}
/// Replace llvm.dbg.* uses of MetadataAsValue(ValueAsMetadata(V)) outside BB
More information about the llvm-commits
mailing list