From 5d334de541096850bd885817be4c3c0da121af94 Mon Sep 17 00:00:00 2001 From: Vassil Vassilev <v.g.vassilev@gmail.com> Date: Tue, 9 Apr 2019 10:01:17 +0300 Subject: [PATCH] [cling] Resize the memory cache before entering the loop. This prevents the vector to be reallocated if the size exceeds the capacity of the vector causing invalid pointer accesses. Fixes ROOT-7749. --- .../cling/lib/Interpreter/LookupHelper.cpp | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/interpreter/cling/lib/Interpreter/LookupHelper.cpp b/interpreter/cling/lib/Interpreter/LookupHelper.cpp index c550bc9129c..2f27e5d9ac0 100644 --- a/interpreter/cling/lib/Interpreter/LookupHelper.cpp +++ b/interpreter/cling/lib/Interpreter/LookupHelper.cpp @@ -1588,22 +1588,18 @@ namespace cling { // // Create the array of Expr from the array of Types. // - - typedef llvm::SmallVectorImpl<QualType>::const_iterator iterator; - for(iterator iter = GivenTypes.begin(), end = GivenTypes.end(); - iter != end; - ++iter) { - const clang::QualType QT = iter->getCanonicalType(); + assert(!ExprMemory.size() && "Size must be 0"); + ExprMemory.resize(GivenTypes.size() + 1); + for(size_t i = 0, e = GivenTypes.size(); i < e; ++i) { + const clang::QualType QT = GivenTypes[i].getCanonicalType(); { ExprValueKind VK = VK_RValue; if (QT->getAs<LValueReferenceType>()) { VK = VK_LValue; } clang::QualType NonRefQT(QT.getNonReferenceType()); - unsigned int slot = ExprMemory.size(); - ExprMemory.resize(slot+1); - Expr* val = new (&ExprMemory[slot]) OpaqueValueExpr(SourceLocation(), - NonRefQT, VK); + Expr* val = new (&ExprMemory[i]) OpaqueValueExpr(SourceLocation(), + NonRefQT, VK); GivenArgs.push_back(val); } } @@ -1656,6 +1652,9 @@ namespace cling { if (QT->getAs<LValueReferenceType>()) { VK = VK_LValue; } + // FIXME: This is potentially dangerous because if the capacity exceeds + // the reserved capacity of ExprMemory, it will reallocate and cause + // memory corruption on the OpaqueValueExpr. See ROOT-7749. clang::QualType NonRefQT(QT.getNonReferenceType()); ExprMemory.resize(++nargs); new (&ExprMemory[nargs-1]) OpaqueValueExpr(TSI->getTypeLoc().getLocStart(), -- GitLab