Problem with httpd and POST data for cgi, and patch

Ralf Friedl Ralf.Friedl at online.de
Fri Oct 12 13:20:21 UTC 2007


Hi

I found a problem with httpd and POST data for cgi programs.

get_line() is used to read the header. This function uses hdr_buf with 
hdr_ptr and hdr_cnt to keep track of the current position. For cgi 
programs cgi_io_loop_and_exit() is called to transfer the POST data to 
the cgi and the result back.

The request variable Content-Length contains the length of the POST 
data. cgi_io_loop_and_exit() tries to send (hdr_cnt + post_len) bytes to 
the cgi. But at this point, the actual header is already read, so 
whatever is left in hdr_cnt ist actally not the header, but (part of) 
the POST data.

In the following (simplified) example, assuming the whole request was 
read in one block, after reading the header, hdr_cnt is 10, and post_len 
is also 10. httpd will write the 10 bytes from hdr_ptr to the cgi (which 
is correct) and then wait for additional 10 bytes (post_len) from the 
network, which will never come, as they are already received. The cgi 
program won't receive EOF and, depending on the program, wait forever 
for more input.

So the bytes transferred from hdr_cnt should be subtracted from 
post_len. I'm not sure whether it might be a legitimate reason for 
(hdr_cnt > post_len),  but I included a check for this just in case.

The patch is against SVN 20228.

Regards
Ralf Friedl


POST /cgi-bin/test
Content-Length: 10

1234567890



--- networking/httpd.c~ 2007-10-12 14:38:42.000000000 +0200
+++ networking/httpd.c  2007-10-12 14:50:44.000000000 +0200
@@ -1102,6 +1102,10 @@
                        if (count > 0) {
                                hdr_ptr += count;
                                hdr_cnt -= count;
+                               if (post_len >= count)
+                                       post_len -= count;
+                               else
+                                       post_len = 0; /* should not 
happen, maybe check for post_len < hdr_cnt? */
                        } else {
                                /* EOF/broken pipe to CGI, stop piping 
POST data */
                                hdr_cnt = post_len = 0;




More information about the busybox mailing list