diff options
author | "Vladimir N. Oleynik" | 2005-12-26 17:26:59 +0000 |
---|---|---|
committer | "Vladimir N. Oleynik" | 2005-12-26 17:26:59 +0000 |
commit | 0bf67e849a8846bd5207b7f17b186ddba931c7fa (patch) | |
tree | b8afa0963b563a63fd9c8ff81571df7b0435a361 | |
parent | ce88793698eb7d53034ff4489f6d484f2b03f8ce (diff) | |
download | busybox-0bf67e849a8846bd5207b7f17b186ddba931c7fa.zip busybox-0bf67e849a8846bd5207b7f17b186ddba931c7fa.tar.gz |
remove buffer overflow by Erik and decodeString problem by Glenn, add error check of decodeString as Apache
-rw-r--r-- | networking/httpd.c | 29 |
1 files changed, 23 insertions, 6 deletions
diff --git a/networking/httpd.c b/networking/httpd.c index 76c4346..b057746 100644 --- a/networking/httpd.c +++ b/networking/httpd.c @@ -747,7 +747,7 @@ static char *encodeString(const char *string) /* take the simple route and encode everything */ /* could possibly scan once to get length. */ int len = strlen(string); - char *out = malloc(len*5 +1); + char *out = malloc(len * 6 + 1); char *p=out; char ch; @@ -792,10 +792,21 @@ static char *decodeString(char *orig, int flag_plus_to_space) if (*ptr == '+' && flag_plus_to_space) { *string++ = ' '; ptr++; } else if (*ptr != '%') *string++ = *ptr++; else { - unsigned int value; - sscanf(ptr+1, "%2X", &value); - *string++ = value; - ptr += 3; + unsigned int value1, value2; + + ptr++; + if(sscanf(ptr, "%1X", &value1) != 1 || + sscanf(ptr+1, "%1X", &value2) != 1) { + if(!flag_plus_to_space) + return NULL; + *string++ = '%'; + } else { + value1 = value1 * 16 + value2; + if(value1 == '/' || value1 == 0) + return orig+1; + *string++ = value1; + ptr += 2; + } } } *string = '\0'; @@ -1604,7 +1615,13 @@ BAD_REQUEST: *purl = ' '; count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank); - decodeString(buf, 0); + test = decodeString(buf, 0); + if(test == NULL) + goto BAD_REQUEST; + if(test == (buf+1)) { + sendHeaders(HTTP_NOT_FOUND); + break; + } if (count < 1 || buf[0] != '/') { /* Garbled request/URL */ goto BAD_REQUEST; |