I have re-uploaded a patch to fix the problem on all versions of httpd 1.2.0 through 1.3.22. This time I added the four lines that check for a negative return value from atol, even though there has been no evidence of any such error in the standard C libraries.
To the person who deleted my prior patch: You just wasted my Sunday afternoon. Even if the patch didn't, by some stretch of your imagination, suffice for the broken atol case, you prevented people from protecting themselves against a published exploit script that doesn't even use content-length as an attack. Do not remove my patch unless you replace it with a better fix that is known to apply for that version and compile on all platforms. -1 to any additions of ap_strtol to prior versions of Apache. That introduced more problems than it fixed. There is no reason to work around the operating system when a simple fix to our own code is necessary and sufficient to solve the problem. Roy T. Fielding, Chairman, The Apache Software Foundation ([EMAIL PROTECTED]) <http://www.apache.org/>
Please see <http://httpd.apache.org/info/security_bulletin_20020620.txt> This patch fixes the known vulnerability of chunk size reads, and a potential vulnerability for content-length reads on systems with a broken atol() implementation, for all versions of Apache httpd 1.2.0 through 1.3.22. Apache httpd 1.3.23 through 1.3.25 require a more extensive patch and should upgrade to the latest version of Apache httpd. All Apache users are encouraged to upgrade to httpd 1.3.26 (or later) or httpd 2.0.39 (or later). This patch is for those people who cannot upgrade for reasons beyond their control. --- apache_1.3.22/src/main/http_protocol_orig.c Fri Jun 22 05:43:54 2001 +++ apache_1.3.22/src/main/http_protocol.c Sun Jun 23 15:56:34 2002 @@ -1913,6 +1913,9 @@ } r->remaining = atol(lenp); + if (r->remaining < 0) { + return HTTP_BAD_REQUEST; + } } if ((r->read_body == REQUEST_NO_BODY) && @@ -2049,6 +2052,10 @@ } len_to_read = get_chunk_size(buffer); + if (len_to_read < 0) { + r->connection->keepalive = -1; + return -1; + } if (len_to_read == 0) { /* Last chunk indicated, get footers */ if (r->read_body == REQUEST_CHUNKED_DECHUNK) {