aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenys Vlasenko <vda.linux@googlemail.com>2011-12-16 01:37:02 +0100
committerDenys Vlasenko <vda.linux@googlemail.com>2011-12-16 01:37:02 +0100
commitb05cd6b7a768039fa799f62634bdc83cb5803ed7 (patch)
tree74c58f2181aa60a78e63c9cb50db270c7d7aa4f0
parentcda6ea905d448e2a2058b5eb44db50b256659b50 (diff)
downloadbusybox-w32-b05cd6b7a768039fa799f62634bdc83cb5803ed7.tar.gz
busybox-w32-b05cd6b7a768039fa799f62634bdc83cb5803ed7.tar.bz2
busybox-w32-b05cd6b7a768039fa799f62634bdc83cb5803ed7.zip
httpd: fix /../ sanitization (had one extra semicolon). rewrote it
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r--networking/httpd.c32
1 files changed, 19 insertions, 13 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 0356e4c1b..f52785bf4 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2012,30 +2012,36 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
2012 /* Algorithm stolen from libbb bb_simplify_path(), 2012 /* Algorithm stolen from libbb bb_simplify_path(),
2013 * but don't strdup, retain trailing slash, protect root */ 2013 * but don't strdup, retain trailing slash, protect root */
2014 urlp = tptr = urlcopy; 2014 urlp = tptr = urlcopy;
2015 do { 2015 for (;;) {
2016 if (*urlp == '/') { 2016 if (*urlp == '/') {
2017 /* skip duplicate (or initial) slash */ 2017 /* skip duplicate (or initial) slash */
2018 if (*tptr == '/') { 2018 if (*tptr == '/') {
2019 continue; 2019 goto next_char;
2020 } 2020 }
2021 if (*tptr == '.') { 2021 if (*tptr == '.') {
2022 /* skip extra "/./" */ 2022 if (tptr[1] == '.' && (tptr[2] == '/' || tptr[2] == '\0')) {
2023 if (tptr[1] == '/' || !tptr[1]) { 2023 /* "..": be careful */
2024 continue; 2024 /* protect root */
2025 } 2025 if (urlp == urlcopy)
2026 /* "..": be careful */
2027 if (tptr[1] == '.' && (tptr[2] == '/' || !tptr[2])) {
2028 ++tptr;
2029 if (urlp == urlcopy) /* protect root */
2030 send_headers_and_exit(HTTP_BAD_REQUEST); 2026 send_headers_and_exit(HTTP_BAD_REQUEST);
2031 while (*--urlp != '/') /* omit previous dir */; 2027 /* omit previous dir */
2028 while (*--urlp != '/')
2032 continue; 2029 continue;
2030 /* skip to "./" or ".<NUL>" */
2031 tptr++;
2032 }
2033 if (tptr[1] == '/' || tptr[1] == '\0') {
2034 /* skip extra "/./" */
2035 goto next_char;
2033 } 2036 }
2034 } 2037 }
2035 } 2038 }
2036 *++urlp = *tptr; 2039 *++urlp = *tptr;
2037 } while (*++tptr); 2040 if (*urlp == '\0')
2038 *++urlp = '\0'; /* terminate after last character */ 2041 break;
2042 next_char:
2043 tptr++;
2044 }
2039 2045
2040 /* If URL is a directory, add '/' */ 2046 /* If URL is a directory, add '/' */
2041 if (urlp[-1] != '/') { 2047 if (urlp[-1] != '/') {