[cups.bugs] [HIGH] STR #3324: cupsd frees memory without cleaning up existing references

Maciej BliziƄski maciej.blizinski at gmail.com
Fri Sep 4 08:43:21 PDT 2009


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

[STR New]

The issue showed up when cups-1.3.11 was compiled without optimization
using Sun Studio 12 compiler. The symptom is that cupsd segfaults a couple
seconds after starting up.

Here are what I think is happening:

1. After starting cupsd, there is a printer which is being added to the
printer list.

2. Data put into p->filetype is being read from mimeAddType(), which uses
cached data from mimeType().

p1->filetype points at addr1

3. There one more call to to cupsAddPrinter(), with the same printer name.
(It probably happens because printers are being added from other
printservers, and there's more than one printserver pointing to this
printer.) A new cupsd_printer_s data structure is being allocated.

4. mimeAddType() is called again to retrieve a pointer for p->filetype.
Lines 86-87 of type.c (that's the version 1.3.11) say:

 /*
  * See if the type already exists; if so, return the existing type...
  */

   if ((temp = mimeType(mime, super, type)) != NULL)
    return (temp);

The result is that the two printers point to the same address, the same
mime_type_t data structure.

p1->filetype points at addr1
p2->filetype points at addr2

5. One of the printers is being renamed. Upon the rename, its data
structures get deallocated. Specifically, there's a call to
mimeDeleteType() (from type.c, line 151), which frees the memory to which
both p->filetype attributes are pointing.

6. calloc() is being called to allocate memory for p->filetype for the new
printer. At this point, inspecting both p->filetype attributes reveals that
they point to different addresses. The printer being renamed has a new
address, while the other printer (with the same name) uses the old
(deallocated) address, which eventually results in data corruption and a
segfault.

addr1 is freed
p1->filetype points at addr2
p2->filetype points at addr1



A simple workaround is to comment out lines 86-87 of type.c, so that there
are no shared p->filetype attributes. After commenting those two lines out,
cupsd doesn't segfault any more.

cupsd, when compiled with optimization flags (-x02), with the same
compiler, on the same host, runs fine. It could be explained by calloc()
allocating the same data structure at the same memory address.

Link: http://www.cups.org/str.php?L3324
Version: 1.3.11





More information about the cups mailing list