diff options
author | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-12-26 17:26:59 +0000 |
---|---|---|
committer | "Vladimir N. Oleynik" <dzo@simtreas.ru> | 2005-12-26 17:26:59 +0000 |
commit | 0bf67e849a8846bd5207b7f17b186ddba931c7fa (patch) | |
tree | b8afa0963b563a63fd9c8ff81571df7b0435a361 | |
parent | ce88793698eb7d53034ff4489f6d484f2b03f8ce (diff) | |
download | busybox-w32-0bf67e849a8846bd5207b7f17b186ddba931c7fa.tar.gz busybox-w32-0bf67e849a8846bd5207b7f17b186ddba931c7fa.tar.bz2 busybox-w32-0bf67e849a8846bd5207b7f17b186ddba931c7fa.zip |
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 76c434628..b057746c8 100644 --- a/networking/httpd.c +++ b/networking/httpd.c | |||
@@ -747,7 +747,7 @@ static char *encodeString(const char *string) | |||
747 | /* take the simple route and encode everything */ | 747 | /* take the simple route and encode everything */ |
748 | /* could possibly scan once to get length. */ | 748 | /* could possibly scan once to get length. */ |
749 | int len = strlen(string); | 749 | int len = strlen(string); |
750 | char *out = malloc(len*5 +1); | 750 | char *out = malloc(len * 6 + 1); |
751 | char *p=out; | 751 | char *p=out; |
752 | char ch; | 752 | char ch; |
753 | 753 | ||
@@ -792,10 +792,21 @@ static char *decodeString(char *orig, int flag_plus_to_space) | |||
792 | if (*ptr == '+' && flag_plus_to_space) { *string++ = ' '; ptr++; } | 792 | if (*ptr == '+' && flag_plus_to_space) { *string++ = ' '; ptr++; } |
793 | else if (*ptr != '%') *string++ = *ptr++; | 793 | else if (*ptr != '%') *string++ = *ptr++; |
794 | else { | 794 | else { |
795 | unsigned int value; | 795 | unsigned int value1, value2; |
796 | sscanf(ptr+1, "%2X", &value); | 796 | |
797 | *string++ = value; | 797 | ptr++; |
798 | ptr += 3; | 798 | if(sscanf(ptr, "%1X", &value1) != 1 || |
799 | sscanf(ptr+1, "%1X", &value2) != 1) { | ||
800 | if(!flag_plus_to_space) | ||
801 | return NULL; | ||
802 | *string++ = '%'; | ||
803 | } else { | ||
804 | value1 = value1 * 16 + value2; | ||
805 | if(value1 == '/' || value1 == 0) | ||
806 | return orig+1; | ||
807 | *string++ = value1; | ||
808 | ptr += 2; | ||
809 | } | ||
799 | } | 810 | } |
800 | } | 811 | } |
801 | *string = '\0'; | 812 | *string = '\0'; |
@@ -1604,7 +1615,13 @@ BAD_REQUEST: | |||
1604 | *purl = ' '; | 1615 | *purl = ' '; |
1605 | count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank); | 1616 | count = sscanf(purl, " %[^ ] HTTP/%d.%*d", buf, &blank); |
1606 | 1617 | ||
1607 | decodeString(buf, 0); | 1618 | test = decodeString(buf, 0); |
1619 | if(test == NULL) | ||
1620 | goto BAD_REQUEST; | ||
1621 | if(test == (buf+1)) { | ||
1622 | sendHeaders(HTTP_NOT_FOUND); | ||
1623 | break; | ||
1624 | } | ||
1608 | if (count < 1 || buf[0] != '/') { | 1625 | if (count < 1 || buf[0] != '/') { |
1609 | /* Garbled request/URL */ | 1626 | /* Garbled request/URL */ |
1610 | goto BAD_REQUEST; | 1627 | goto BAD_REQUEST; |