[cups.bugs] [HIGH] STR #3951: Bad array handling in cups-driverd

Tim Waugh twaugh at redhat.com
Tue Oct 4 08:31:18 PDT 2011


DO NOT REPLY TO THIS MESSAGE.  INSTEAD, POST ANY RESPONSES TO THE LINK BELOW.

[STR New]

cups-driverd ends up using freed memory.  Here's how:

load_ppds() calls load_ppds_dat(), which sets up the two arrays:

  PPDsByName      = cupsArrayNew((cups_array_func_t)compare_names, NULL);
  PPDsByMakeModel = cupsArrayNew((cups_array_func_t)compare_ppds, NULL);

It adds PPDs to the arrays, setting 'found' to 0 as it goes by simply
leaving it unset after the calloc() call.

Next, load_ppds() scans for PPDs to add.  When a .drv file is found, it
adds PPDs to the array, setting 'found' to 1.

The situation at this point is that .drv files will likely have two
identical entries in each array for each model they describe, one with
found=0 and the other with found=1.

The trouble comes when load_ppds() wants to cull unfound PPDs:

  for (ppd = (ppd_info_t *)cupsArrayFirst(PPDsByName);
       ppd;
       ppd = (ppd_info_t *)cupsArrayNext(PPDsByName))
    if (!ppd->found)
    {
     /*
      * Remove this PPD file from the list...
      */

      cupsArrayRemove(PPDsByName, ppd);
      cupsArrayRemove(PPDsByMakeModel, ppd);
      free(ppd);

      ChangedPPD = 1;
    }

This doesn't do what it looks like it will.  The PPDsByName handling is
all fine, but this line has an unintended effect:

      cupsArrayRemove(PPDsByMakeModel, ppd);

It doesn't remove ppd from the array.  Instead, it searches through the
array, looking for an entry that matches ppd, using compare_ppds().  If
there are multiple entries, it returns the first one that matches.

This may well be the wrong one, i.e. one where found=1.

I guess the fix is to ensure that p->found is taken into account when
sorting, so that found=0 sorts before found=1.

Another approach would be for array.h to grow a function for removing the
current element; then cupsArrayFind()/cupsArrayNext() could be used to
find the right element to remove.

Original report:
  https://bugzilla.redhat.com/show_bug.cgi?id=742989

Link: http://www.cups.org/str.php?L3951
Version: 1.5.0





More information about the cups mailing list