summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHenning Brauer <henning@cvs.openbsd.org>2002-06-17 19:15:50 +0000
committerHenning Brauer <henning@cvs.openbsd.org>2002-06-17 19:15:50 +0000
commitd27320aa6ec1696185c414c78ff94550b5126a50 (patch)
treeaca4ce21dd3aeddf018119a66b66201b1bda937b
parent9194de5fc9fdebaa2b7c255608e8c7b89750cd2c (diff)
The Real Fix for the buffer overflow; from apache.org
ok beck@
-rw-r--r--usr.sbin/httpd/src/main/http_protocol.c31
1 files changed, 24 insertions, 7 deletions
diff --git a/usr.sbin/httpd/src/main/http_protocol.c b/usr.sbin/httpd/src/main/http_protocol.c
index f86be0d4e06..b373c76ea83 100644
--- a/usr.sbin/httpd/src/main/http_protocol.c
+++ b/usr.sbin/httpd/src/main/http_protocol.c
@@ -2028,21 +2028,34 @@ API_EXPORT(int) ap_should_client_block(request_rec *r)
static long get_chunk_size(char *b)
{
long chunksize = 0;
+ long chunkbits = sizeof(long) * 8;
- while (ap_isxdigit(*b)) {
+ /* Skip leading zeros */
+ while (*b == '0') {
+ ++b;
+ }
+
+ while (ap_isxdigit(*b) && (chunkbits > 0)) {
int xvalue = 0;
- /* This works even on EBCDIC. */
- if (*b >= '0' && *b <= '9')
+ if (*b >= '0' && *b <= '9') {
xvalue = *b - '0';
- else if (*b >= 'A' && *b <= 'F')
+ }
+ else if (*b >= 'A' && *b <= 'F') {
xvalue = *b - 'A' + 0xa;
- else if (*b >= 'a' && *b <= 'f')
+ }
+ else if (*b >= 'a' && *b <= 'f') {
xvalue = *b - 'a' + 0xa;
+ }
chunksize = (chunksize << 4) | xvalue;
+ chunkbits -= 4;
++b;
}
+ if (ap_isxdigit(*b) && (chunkbits <= 0)) {
+ /* overflow */
+ return -1;
+ }
return chunksize;
}
@@ -2068,7 +2081,7 @@ API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
unsigned long max_body;
if (!r->read_chunked) { /* Content-length read */
- len_to_read = (r->remaining > (unsigned int)bufsiz) ? bufsiz : r->remaining;
+ len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
len_read = ap_bread(r->connection->client, buffer, len_to_read);
if (len_read <= 0) {
if (len_read < 0)
@@ -2127,6 +2140,10 @@ API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
}
r->remaining = -1; /* Indicate footers in-progress */
}
+ else if (len_to_read < 0) {
+ r->connection->keepalive = -1;
+ return -1;
+ }
else {
r->remaining = len_to_read;
}
@@ -2180,7 +2197,7 @@ API_EXPORT(long) ap_get_client_block(request_rec *r, char *buffer, int bufsiz)
/* Otherwise, we are in the midst of reading a chunk of data */
- len_to_read = (r->remaining > (unsigned int)bufsiz) ? bufsiz : r->remaining;
+ len_to_read = (r->remaining > bufsiz) ? bufsiz : r->remaining;
len_read = ap_bread(r->connection->client, buffer, len_to_read);
if (len_read <= 0) {