Bug 146850 - [PATCH] cupsd segfault when SIGCHLD received
[PATCH] cupsd segfault when SIGCHLD received
Product: Red Hat Enterprise Linux 3
Classification: Red Hat
Component: cups (Show other bugs)
All Linux
medium Severity medium
: ---
: ---
Assigned To: Tim Waugh
Depends On:
Blocks: 156320 164641
  Show dependency treegraph
Reported: 2005-02-01 21:53 EST by David Lehman
Modified: 2007-11-30 17:07 EST (History)
1 user (show)

See Also:
Fixed In Version: RHBA-2005-631
Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of:
Last Closed: 2005-09-28 12:57:28 EDT
Type: ---
Regression: ---
Mount Type: ---
Documentation: ---
Verified Versions:
Category: ---
oVirt Team: ---
RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: ---

Attachments (Terms of Use)
Patch to block sigchld while in ReadConfiguration (1.80 KB, patch)
2005-02-01 21:53 EST, David Lehman
no flags Details | Diff

  None (edit)
Description David Lehman 2005-02-01 21:53:55 EST
Description of problem:
If cupsd gets a SIGHUP and is in the process of reloading the configuration when
it receives a SIGCHLD it can segfault in sigchld_handler. 

Version-Release number of selected component (if applicable):

How reproducible:

Steps to Reproduce:
1. send SIGHUP to cupsd
Actual results:
cupsd exits with sig 11

Expected results:
cupsd reloads configuration and continues running

Additional info:
Here is the customer's report:
Core was generated by `cupsd'.
 Program terminated with signal 11, Segmentation fault.
 #0  sigchld_handler (sig=17) at main.c:775
 775           if (job->state != NULL &&
 (gdb) bt
 #0  sigchld_handler (sig=17) at main.c:775
 #1  <signal handler called>
 #2  0xb7376edb in _int_free () from /lib/tls/libc.so.6
 #3  0xb7375e68 in free () from /lib/tls/libc.so.6
 #4  0xb74899f5 in _ipp_free_attr () from /usr/lib/libcups.so.2
 #5  0xb748822a in ippDelete () from /usr/lib/libcups.so.2
 #6  0x08068a50 in FreeAllJobs () at job.c:375
 #7  0x08054951 in ReadConfiguration () at conf.c:177
 #8  0x0805c5a4 in main (argc=1, argv=0xbfffb134) at main.c:411
 #9  0xb731a768 in __libc_start_main () from /lib/tls/libc.so.6
 #10 0x0804c401 in _start ()

Investigating an above backtrace,
I guess that an invalid pointer operation in "sigchld_handler" function which is
executed when cupsd receives "SIGCHLD"
signal causes it abnormal termination with "Segmentation fault".

A part of sigchld_hanlder function is:
 770        /*
 771         * Lookup the PID in the jobs list...
 772         */
 774         for (job = Jobs; job != NULL; job = job->next)
 775           if (job->state != NULL &&
 776               job->state->values[0].integer == IPP_JOB_PROCESSING)
 777           {

It seems that cupsd terminated abnormally in "Jobs" list operation.

(gdb) print job
$1 = (job_t *) 0x64

Therefore I am sure that cupsd terminated abnormally with "Segmentation fault"
because of an invalid pointer operation.

Moreover, I traced above backtrace and then we find "FreeAllJobs" function at #6.
Looking the following lines in "FreeAllJobs" function on this backtrace #6:     
 (gdb) up 6
 #6  0x08068a50 in FreeAllJobs () at job.c:375
 375         ippDelete(job->attrs);
 (gdb) list
 371       for (job = Jobs; job; job = next)
 372       {
 373         next = job->next;
 375         ippDelete(job->attrs);
 376         free(job->filetypes);
 377         free(job);
 378       }

Apparently, it seems to be while the same "Jobs" list was operated.

Referring the "next" value at this time:
 (gdb) print next
 $2 = (job_t *) 0x80c3918
 (gdb) print job
 $3 = (job_t *) 0x80c28c0

It seems that these pointers are valid.

(gdb) down 6
#0  sigchld_handler (sig=17) at main.c:775
775           if (job->state != NULL &&

Returning to #0 backtrace and then tracing "Jobs" list pointer one after another:
 (gdb) print Jobs
 $4 = (job_t *) 0x80ba600
 (gdb) print Jobs->next
 $5 = (struct job_str *) 0x80bb598
 (gdb) print Jobs->next->next
 $6 = (struct job_str *) 0x64
These are same on backtrace #6, too.

Therefore, it can be judged that the trouble occurrence cause guessed first was

Summarizing this trouble occurrence cause:
 1) "cupsd" received SIGHUP signal
 2) "cupsd" did the following actions:
 [1] Sending SIGTERM(or SIGKILL) signal to all children processes which connect
to their parent process
 [2] Releasing all items which cascade connection to the "Jobs" list

 3) The parent process, "cupsd" received SIGCHLD signal
 4) Start to perform "sigchld_handler", the signal handler of SIGCHLD
 after interrupting 2)-[2] process temporarily

 5) In the sigchld_handler function, there is processing by which "Jobs" list is
 The problem might occur depending on the timing of "SIGCHLD" interruption.
 At this time, "cupsd" sometimes remains an invalid pointer of "Jobs" list.   
 And then "cupsd" tries to refer an invalid pointer
 when it traces each an element from "Jobs" list one after another in
 And then "cupsd" terminates abnormally.   

Therefore, it can be judged
that it is a timing trouble which occurs because sigchld_handler was called in
"Jobs" list operating.

Correction proposal and reproduction test with a patch:
 I performed the reproduction test with the patch which is fixed that cupsd is
blocking SIGCHLD signal while "Jobs" list operation,
and then I confirmed that this problem didn't occur.
Comment 1 David Lehman 2005-02-01 21:53:55 EST
Created attachment 110539 [details]
Patch to block sigchld while in ReadConfiguration
Comment 2 Tim Waugh 2005-02-02 07:16:13 EST
Reported upstream:
Comment 3 Tim Waugh 2005-02-02 07:40:44 EST
Fixed in CVS.
Comment 15 Red Hat Bugzilla 2005-09-28 12:57:28 EDT
An advisory has been issued which should help the problem
described in this bug report. This report is therefore being
closed with a resolution of ERRATA. For more information
on the solution and/or where to find the updated files,
please follow the link below. You may reopen this bug report
if the solution does not work for you.


Note You need to log in before you can comment on or make changes to this bug.