[git commit] httpd: fix /../ sanitization (had one extra semicolon). rewrote it

Denys Vlasenko vda.linux at googlemail.com
Fri Dec 16 00:37:02 UTC 2011


commit: http://git.busybox.net/busybox/commit/?id=b05cd6b7a768039fa799f62634bdc83cb5803ed7
branch: http://git.busybox.net/busybox/commit/?id=refs/heads/master

Signed-off-by: Denys Vlasenko <vda.linux at googlemail.com>
---
 networking/httpd.c |   32 +++++++++++++++++++-------------
 1 files changed, 19 insertions(+), 13 deletions(-)

diff --git a/networking/httpd.c b/networking/httpd.c
index 0356e4c..f52785b 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -2012,30 +2012,36 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
 	/* Algorithm stolen from libbb bb_simplify_path(),
 	 * but don't strdup, retain trailing slash, protect root */
 	urlp = tptr = urlcopy;
-	do {
+	for (;;) {
 		if (*urlp == '/') {
 			/* skip duplicate (or initial) slash */
 			if (*tptr == '/') {
-				continue;
+				goto next_char;
 			}
 			if (*tptr == '.') {
-				/* skip extra "/./" */
-				if (tptr[1] == '/' || !tptr[1]) {
-					continue;
-				}
-				/* "..": be careful */
-				if (tptr[1] == '.' && (tptr[2] == '/' || !tptr[2])) {
-					++tptr;
-					if (urlp == urlcopy) /* protect root */
+				if (tptr[1] == '.' && (tptr[2] == '/' || tptr[2] == '\0')) {
+					/* "..": be careful */
+					/* protect root */
+					if (urlp == urlcopy)
 						send_headers_and_exit(HTTP_BAD_REQUEST);
-					while (*--urlp != '/') /* omit previous dir */;
+					/* omit previous dir */
+					while (*--urlp != '/')
 						continue;
+					/* skip to "./" or ".<NUL>" */
+					tptr++;
+				}
+				if (tptr[1] == '/' || tptr[1] == '\0') {
+					/* skip extra "/./" */
+					goto next_char;
 				}
 			}
 		}
 		*++urlp = *tptr;
-	} while (*++tptr);
-	*++urlp = '\0';       /* terminate after last character */
+		if (*urlp == '\0')
+			break;
+ next_char:
+		tptr++;
+	}
 
 	/* If URL is a directory, add '/' */
 	if (urlp[-1] != '/') {


More information about the busybox-cvs mailing list