From f99b06213e39c3e2d46db243d2509c42cc63c752 Mon Sep 17 00:00:00 2001 From: Julian Andres Klode Date: Mon, 7 Mar 2016 01:32:08 +0100 Subject: apt-pkg/algorithms.cc: Avoid stack buffer overflow in KillList Dynamically allocate KillList in order to avoid an overflow when more than 100 elements would be written to it. This happened while playing around with the status file from Bug#701069 on a modern system. --- apt-pkg/algorithms.cc | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/apt-pkg/algorithms.cc b/apt-pkg/algorithms.cc index 4b84b8324..ee4787b38 100644 --- a/apt-pkg/algorithms.cc +++ b/apt-pkg/algorithms.cc @@ -725,6 +725,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) changing a breaks c) */ bool Change = true; bool const TryFixByInstall = _config->FindB("pkgProblemResolver::FixByInstall", true); + std::vector KillList; for (int Counter = 0; Counter != 10 && Change == true; Counter++) { Change = false; @@ -767,12 +768,12 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) clog << "Investigating (" << Counter << ") " << I << endl; // Isolate the problem dependency - PackageKill KillList[100]; - PackageKill *LEnd = KillList; bool InOr = false; pkgCache::DepIterator Start; pkgCache::DepIterator End; - PackageKill *OldEnd = LEnd; + size_t OldSize = 0; + + KillList.resize(0); enum {OrRemove,OrKeep} OrOp = OrRemove; for (pkgCache::DepIterator D = Cache[I].InstVerIter(Cache).DependsList(); @@ -782,7 +783,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) if (Start == End) { // Decide what to do - if (InOr == true && OldEnd == LEnd) + if (InOr == true && OldSize == KillList.size()) { if (OrOp == OrRemove) { @@ -816,7 +817,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) continue; InOr = Start != End; - OldEnd = LEnd; + OldSize = KillList.size(); } else { @@ -979,10 +980,8 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) if (Debug == true) clog << " Added " << Pkg.FullName(false) << " to the remove list" << endl; - - LEnd->Pkg = Pkg; - LEnd->Dep = End; - LEnd++; + + KillList.push_back({Pkg, End}); if (Start.IsNegative() == false) break; @@ -1032,7 +1031,7 @@ bool pkgProblemResolver::ResolveInternal(bool const BrokenFix) // Apply the kill list now if (Cache[I].InstallVer != 0) { - for (PackageKill *J = KillList; J != LEnd; J++) + for (auto J = KillList.begin(); J != KillList.end(); J++) { Change = true; if ((Cache[J->Dep] & pkgDepCache::DepGNow) == 0) -- cgit v1.2.3