On Sun, Apr 24, 2005 at 10:57:01PM +0200, Gergely Nagy wrote:
> Anyways, a fix is in the works, and will be in the next upstream
> release. (A workaround is ready already, but I want to fix this
> properly).
> 

Hello,

What is the status of fixing this bug?  The following is my investigate
of the bug.

(1) Install thy.  Set "THY_LISTEN=127.0.0.1/8001" in /etc/default/thy,
restart thy.

(2) Good CGI file.

$ cat /usr/lib/cgi-bin/good.sh 
#!/bin/sh
echo -en "Content-type: text/html\n\n"
echo "hello, world."

This works fine with both thy and apache.

(3) Bad CGI file.

$ cat /usr/lib/cgi-bin/bad.sh 
#!/bin/sh
#echo -en "Content-type: text/html\n\n"
#echo "hello, world."

Apache shows 500 error (Internal Server Error), but thy makes firefox
wait forever.  wget also loops through multiple tries.  The following
command says "No data received".

$ wget -t1 http://localhost:8001/cgi-bin/bad.sh
--18:41:20--  http://localhost:8001/cgi-bin/bad.sh
           => `bad.sh'
Resolving localhost... 127.0.0.1
Connecting to localhost|127.0.0.1|:8001... connected.
HTTP request sent, awaiting response... No data received.
Giving up.

ngrep confirms nothing is sent back to wget.

(4) Dive into the source code.

[src/daemon.c:786]: premature end of file from CGI is detected and
logged.  control flows to:

[src/daemon.c:814]: this code arranges the session to output
HTTP_STATUS_500 to the client, and the CGI program to be killed by
SIGKILL(?).  This is very good, but:

Before any data is sent to the client, the CGI program exited (in this
case the program terminates, but otherwise it would be killed by
SIGKILL).  

[src/main.c:145]: for each terminated child process (CGI), queue_del is
called, which calls session_kill, which shutdown socket connections.
Therefore no data can be sent to the client.

Recommended fix: do not call queue_del in cleanup_children.

BTW, it seems there is a race condition around the variable sigchild.
Eg, if a SIGCHLD happens right after the while loop[src/main.c:169],
sigchild will be reset to zero.  This child is not waited until any
other child dies.

Recommended fix: do not use variable sigchild, instead, use a pipe to
send the information[0].

[0] http://cr.yp.to/docs/selfpipe.html

Hope this helps fix the bug.

Regards,
qingning

Attachment: signature.asc
Description: Digital signature

Reply via email to