Browse Source

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.
tags/debian/1.2.6
Julian Andres Klode 5 years ago
parent
commit
f99b06213e
1 changed files with 9 additions and 10 deletions
  1. +9
    -10
      apt-pkg/algorithms.cc

+ 9
- 10
apt-pkg/algorithms.cc View File

@@ -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<PackageKill> 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)


Loading…
Cancel
Save