Patches for various crashers
- To: deity@lists.debian.org
- Subject: Patches for various crashers
- From: Christoph Pfisterer <cp@chrisp.de>
- Date: Sat, 8 Sep 2001 14:08:50 +0200
- Message-id: <p05101005b7bfb56d1df0@[192.168.2.8]>
Hi all!
I've discovered several crashing bugs in apt 0.5.3 while porting it
to Mac OS X / Darwin. Some may be only potential bugs, but at least
one is real and may affect Debian, too. I haven't had the time to
port my patches to 0.5.4 yet, but I will do so soon and send you the
patches on request.
The first bug is in cmdline/apt-cache.cc, function DumpAvail. When
all packages are selected for output, the list lacks a sentinel,
which in causes a segfault when writing the data to stdout. This only
happens when there are no virtual packages. Here's a patch to fix it:
diff -ruN apt/cmdline/apt-cache.cc apt-patched/cmdline/apt-cache.cc
--- apt/cmdline/apt-cache.cc Thu Mar 8 03:20:43 2001
+++ apt-patched/cmdline/apt-cache.cc Wed Aug 22 18:26:23 2001
@@ -371,9 +371,11 @@
pkgPolicy Plcy(&Cache);
if (ReadPinFile(Plcy) == false)
return false;
-
- pkgCache::VerFile **VFList = new pkgCache::VerFile
*[Cache.HeaderP->PackageC
ount];
- memset(VFList,0,sizeof(*VFList)*Cache.HeaderP->PackageCount);
+
+ // Make sure we have a sentinel for the list.
+ unsigned long Count = Cache.HeaderP->PackageCount + 1;
+ pkgCache::VerFile **VFList = new pkgCache::VerFile *[Count];
+ memset(VFList,0,sizeof(*VFList)*Count);
// Map versions that we want to write out onto the VerList array.
for (pkgCache::PkgIterator P = Cache.PkgBegin(); P.end() == false; P++)
@@ -426,7 +428,7 @@
VFList[P->ID] = VF;
}
- LocalitySort(VFList,Cache.HeaderP->PackageCount,sizeof(*VFList));
+ LocalitySort(VFList,Count,sizeof(*VFList));
// Iterate over all the package files and write them out.
char *Buffer = new char[Cache.HeaderP->MaxVerFileSize+10];
The other bug (or rather series of bugs) is in apt-pkg/tagfile.cc
(pkgTagSection::Scan) and apt-pkg/tagfile.h (pkgTagSection
definition). On several occations, the code may read or write beyond
the end of an array or buffer. I'm not sure which one caused my
segfaults, but I strongly suspect the loop after the "Double newline
marks the end of the record" comment. If the last char in the
(dynamically allocated and page-aligned) buffer happens to be a
newline, that loop will read beyond the end of the buffer. Other
problems: the AlphaIndex is too small (indexes go from 0x00 to 0xff,
i.e. 0x100 elements) and TagCount must be checked against a smaller
value because the code may write two entries to the Indexes array in
the last iteration. Here's the patch:
diff -ruN apt/apt-pkg/tagfile.cc apt-patched/apt-pkg/tagfile.cc
--- apt/apt-pkg/tagfile.cc Tue Feb 27 05:14:22 2001
+++ apt-patched/apt-pkg/tagfile.cc Fri Sep 7 08:10:00 2001
@@ -187,7 +187,7 @@
return false;
TagCount = 0;
- while (TagCount < sizeof(Indexes)/sizeof(Indexes[0]) && Stop < End)
+ while (TagCount < sizeof(Indexes)/sizeof(Indexes[0])-1 && Stop < End)
{
// Start a new index and add it to the hash
if (isspace(Stop[0]) == 0)
@@ -201,13 +201,13 @@
if (Stop == 0)
return false;
- for (; Stop[1] == '\r' && Stop+1 < End; Stop++);
+ for (; Stop+1 < End && Stop[1] == '\r'; Stop++);
// Double newline marks the end of the record
if (Stop+1 < End && Stop[1] == '\n')
{
Indexes[TagCount] = Stop - Section;
- for (; (Stop[0] == '\n' || Stop[0] == '\r') && Stop < End; Stop++);
+ for (; Stop < End && (Stop[0] == '\n' || Stop[0] == '\r'); Stop++);
return true;
}
diff -ruN apt/apt-pkg/tagfile.h apt-patched/apt-pkg/tagfile.h
--- apt/apt-pkg/tagfile.h Tue Feb 20 08:03:17 2001
+++ apt-patched/apt-pkg/tagfile.h Fri Sep 7 08:10:15 2001
@@ -34,7 +34,7 @@
// We have a limit of 256 tags per section.
unsigned short Indexes[256];
- unsigned short AlphaIndexes[0xff];
+ unsigned short AlphaIndexes[0x100];
unsigned int TagCount;
BTW, I'm assuming from the comments in COMPILING that you're not
interested in my Darwin patches. In case you are, just let me know.
Hope this helps,
chrisp
--
chrisp a.k.a. Christoph Pfisterer "Any sufficiently advanced
cp@chrisp.de - http://chrisp.de bug is indistinguishable
PGP key & geek code available from a feature."
Reply to: