httpd-bugs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From bugzi...@apache.org
Subject DO NOT REPLY [Bug 12068] New: - POST body truncation
Date Tue, 27 Aug 2002 08:51:39 GMT
DO NOT REPLY TO THIS EMAIL, BUT PLEASE POST YOUR BUG 
RELATED COMMENTS THROUGH THE WEB INTERFACE AVAILABLE AT
<http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12068>.
ANY REPLY MADE TO THIS MESSAGE WILL NOT BE COLLECTED AND 
INSERTED IN THE BUG DATABASE.

http://nagoya.apache.org/bugzilla/show_bug.cgi?id=12068

POST body truncation

           Summary: POST body truncation
           Product: Apache httpd-2.0
           Version: 2.0.39
          Platform: Alpha
        OS/Version: Other
            Status: NEW
          Severity: Major
          Priority: Other
         Component: mod_cgi
        AssignedTo: bugs@httpd.apache.org
        ReportedBy: buczek@molgen.mpg.de


During the forwarding of POST/PUT request bodies (eg file upload),
the pipe between the server and the cgi-script might
become filled.
 
This situation - which is sure to happen when the data exceeds a
certain size - is not handled correctly.

The pipe is set to O_NONBLOCK. mod_cgi uses apr_file_write_full()
to write to it. The file write routines from the apr library
follow the usual routine: call write() - if EAGAIN, use
select() to wait for the file to become writeable, then
retry the  write(). They expect, that the write()s may
complete partially.

While this logic works for sockets, it doesn't work
for pipes! write()s to pipes are not generally allowed to succeed
partially. "requests for PIPE_BUF or fewer bytes either succeed
completely and return nbytes, or return -1 and set errno to [EAGAIN]".

It is rather undefined, under what circumstances select() will
call a pipe ready-for-write. On some implementation select()
waits for the pipe to be completly empty. On others, which
has room for just a single byte is called ready-for-write by
select() and friends.

In any case, a 'ready for write' pipe can only accept a
certain number of bytes and never any number of bytes.

So the second write() to the pipe is likely to signal
EAGAIN again. This error is returned by the apr_ routines
and mod_cgi stops forwarding the data (child_stopped_reading = 1)

After upgrade to Apache 2.0 one of our applications, which
utilizes file uploads, stopped working because of this.

The quickfix for me was to set the pipe to blocking, thereby
sacrificing the timeout feature.

==================================================
--- ./modules/generators/mod_cgi.c      2002/08/21 13:08:23
***************
*** 496,503 ****
                  *script_out = procnew->in;
                  if (!*script_out)
                      return APR_EBADF;
-                 apr_file_pipe_timeout_set(*script_out, r->server->timeout);
  
                  *script_err = procnew->err;
                  if (!*script_err)
                      return APR_EBADF;
--- 496,506 ----
                  *script_out = procnew->in;
                  if (!*script_out)
                      return APR_EBADF;
  
+                 /* EAGAIN on write() to pipe even after select() said
writable... set to blocking for now */
+                 /* apr_file_pipe_timeout_set(*script_out, r->server->timeout);
*/
+                 apr_file_pipe_timeout_set(*script_out,-1);
+ 
                  *script_err = procnew->err;
                  if (!*script_err)
                      return APR_EBADF;
==================================================

I don't have a idea for a good solution. A
good solution should include the case, that the
sgi-script starts writing output before it finished
reading input. The apache server process should
handle both directions at the same time.

Ciao
  Donald

---------------------------------------------------------------------
To unsubscribe, e-mail: bugs-unsubscribe@httpd.apache.org
For additional commands, e-mail: bugs-help@httpd.apache.org


Mime
View raw message