[SCCPSolver] Fix use-after-free in markArgInFuncSpecialization
authorSjoerd Meijer <sjoerd.meijer@arm.com>
Tue, 5 Oct 2021 11:12:39 +0000 (12:12 +0100)
committerSjoerd Meijer <sjoerd.meijer@arm.com>
Tue, 5 Oct 2021 11:56:32 +0000 (12:56 +0100)
In SCCPSolver::markArgInFuncSpecialization, the ValueState map may be
reallocated *after* the initial ValueLatticeElement reference is grabbed, but
*before* its use in copy initialization. This causes a use-after-free.  To fix
this, this commit changes the behavior to create the new ValueLatticeElement
before assigning the old one to it.

Patch by: https://github.com/duck-37/

Differential Revision: https://reviews.llvm.org/D111112

llvm/lib/Transforms/Utils/SCCPSolver.cpp

index 4cf99ab..4475474 100644 (file)
@@ -540,8 +540,14 @@ void SCCPInstVisitor::markArgInFuncSpecialization(Function *F, Argument *A,
             E = F->arg_end();
        I != E; ++I, ++J)
     if (J != A && ValueState.count(I)) {
-      ValueState[J] = ValueState[I];
-      pushToWorkList(ValueState[J], J);
+      // Note: This previously looked like this:
+      // ValueState[J] = ValueState[I];
+      // This is incorrect because the DenseMap class may resize the underlying
+      // memory when inserting `J`, which will invalidate the reference to `I`.
+      // Instead, we make sure `J` exists, then set it to `I` afterwards.
+      auto &NewValue = ValueState[J];
+      NewValue = ValueState[I];
+      pushToWorkList(NewValue, J);
     }
 }