diff options
| author | Denys Vlasenko <vda.linux@googlemail.com> | 2011-12-16 01:37:02 +0100 |
|---|---|---|
| committer | Denys Vlasenko <vda.linux@googlemail.com> | 2011-12-16 01:37:02 +0100 |
| commit | b05cd6b7a768039fa799f62634bdc83cb5803ed7 (patch) | |
| tree | 74c58f2181aa60a78e63c9cb50db270c7d7aa4f0 | |
| parent | cda6ea905d448e2a2058b5eb44db50b256659b50 (diff) | |
| download | busybox-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.c | 32 |
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] != '/') { |
