cupsd dies due to double freeing of a remote printer #2656

Closed
michaelrsweet opened this Issue Jan 7, 2008 · 6 comments

Comments

Projects
None yet
1 participant
Collaborator

michaelrsweet commented Jan 7, 2008

Version: 1.3.5
CUPS.org User: h.blischke

Occasionally cupsd tries to double free a remote printer (introduced by polling from another CUPS server).

It might be system dependent (occurred on
2.6.11-1.27_FC3smp #1 SMP Tue May 17 20:43:11 EDT 2005 i686 i686 i386 GNU/Linux

Collaborator

michaelrsweet commented Jan 7, 2008

CUPS.org User: mike

Can you run cupsd in GDB so we can get a real traceback?

gdb /usr/sbin/cupsd
run -f

I don't see how it would be possible for the destination to timeout twice given that we delete it from the array we are iterating...

Collaborator

michaelrsweet commented Jan 7, 2008

CUPS.org User: h.blischke

I suspect the following:

The server which died has a class abl_fu_A3 defined and got a printer with the same name by bwowsing from another CUPS server.

For a backtrace I need a time slot with no production load, which will be available on tuesday to wednesday night, if still required.

Collaborator

michaelrsweet commented Jan 7, 2008

CUPS.org User: mike

OK, I'll still need the backtrace; you can't get both a printer and class with the same name (the dirsvc and IPP code prevents it...)

Collaborator

michaelrsweet commented Jan 7, 2008

CUPS.org User: dwb

This sounds like the problem we hit: if a server deletes a printer and recreates it as a class, all other servers doing browse-poll to that server crash.

Problem appears to be in process_browse_data in dirsvc.c. If an entry comes in with the class bit set, it checks to see if there is already a class of that name but doesn't check if there is a printer of that name. So it creates another entry with same name which ends up pointing to the same mime type entry as the first printer. Then when the first (printer) entry times out and is deleted the mime type entry is deleted out from under the second entry.

I fixed it in cups 1.3.4 with the following patch:

--- cups-1.3.4/scheduler/dirsvc.c 2007-10-01 19:11:47.000000000 -0400
+++ cups-1.3.4p1/scheduler/dirsvc.c 2007-12-10 15:25:53.000000000 -0500
@@ -1862,6 +1862,13 @@
if (!p)
{
/*

  •  \* Make sure there is no old printer of same name defined
    
  •  */
    
  •  if ((p = cupsdFindPrinter(name)) != NULL)
    
  •    cupsdDeletePrinter(p,1);
    
  • /*
    
    • Class doesn't exist; add it...
      */

(I was about to enter an STR for this but you beat me to it...)

Collaborator

michaelrsweet commented Jan 8, 2008

CUPS.org User: mike

OK, a simpler fix is to just use cupsdFindDest() which finds both printers and classes - that allows for a remote printer to transform into a class, and visa-versa.

Collaborator

michaelrsweet commented Jan 8, 2008

"str2656.patch":

Index: scheduler/dirsvc.c

--- scheduler/dirsvc.c (revision 7191)
+++ scheduler/dirsvc.c (working copy)
@@ -1817,9 +1820,9 @@
if (hptr && !hptr)
*hptr = '.'; /
Resource FQDN */

  • if ((p = cupsdFindClass(name)) == NULL && BrowseShortNames)

  • if ((p = cupsdFindDest(name)) == NULL && BrowseShortNames)
    {

  •  if ((p = cupsdFindClass(resource + 9)) != NULL)
    
  •  if ((p = cupsdFindDest(resource + 9)) != NULL)
    

    {
    if (p->hostname && strcasecmp(p->hostname, host))
    {
    @@ -1924,9 +1927,9 @@
    if (hptr && !hptr)
    *hptr = '.'; /
    Resource FQDN */

  • if ((p = cupsdFindPrinter(name)) == NULL && BrowseShortNames)

  • if ((p = cupsdFindDest(name)) == NULL && BrowseShortNames)
    {

  •  if ((p = cupsdFindPrinter(resource + 10)) != NULL)
    
  •  if ((p = cupsdFindDest(resource + 10)) != NULL)
    

    {
    if (p->hostname && strcasecmp(p->hostname, host))
    {

michaelrsweet added this to the Stable milestone Mar 17, 2016

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment