[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Patches for various crashers



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: