[git commit] httpd: defend against attempts to OOM us. Closes 9611

Denys Vlasenko vda.linux at googlemail.com
Thu Jan 26 18:35:40 UTC 2017


commit: https://git.busybox.net/busybox/commit/?id=b4b12bf2344148976d1cd0f17bca0c0fbf7a364c
branch: https://git.busybox.net/busybox/commit/?id=refs/heads/master

We were strdup'ing "Cookie: foo" every time we saw it.

function                                             old     new   delta
handle_incoming_and_exit                            2733    2821     +88

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

diff --git a/networking/httpd.c b/networking/httpd.c
index 39aad90..8703fbd 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -460,11 +460,6 @@ struct globals {
 #define ip_a_d            (G.ip_a_d           )
 #define g_realm           (G.g_realm          )
 #define remoteuser        (G.remoteuser       )
-#define referer           (G.referer          )
-#define user_agent        (G.user_agent       )
-#define host              (G.host             )
-#define http_accept       (G.http_accept      )
-#define http_accept_language (G.http_accept_language)
 #define file_size         (G.file_size        )
 #if ENABLE_FEATURE_HTTPD_RANGES
 #define range_start       (G.range_start      )
@@ -1529,11 +1524,11 @@ static void send_cgi_and_exit(
 #endif
 		}
 	}
-	setenv1("HTTP_USER_AGENT", user_agent);
-	if (http_accept)
-		setenv1("HTTP_ACCEPT", http_accept);
-	if (http_accept_language)
-		setenv1("HTTP_ACCEPT_LANGUAGE", http_accept_language);
+	setenv1("HTTP_USER_AGENT", G.user_agent);
+	if (G.http_accept)
+		setenv1("HTTP_ACCEPT", G.http_accept);
+	if (G.http_accept_language)
+		setenv1("HTTP_ACCEPT_LANGUAGE", G.http_accept_language);
 	if (post_len)
 		putenv(xasprintf("CONTENT_LENGTH=%d", post_len));
 	if (cookie)
@@ -1546,9 +1541,9 @@ static void send_cgi_and_exit(
 		putenv((char*)"AUTH_TYPE=Basic");
 	}
 #endif
-	if (referer)
-		setenv1("HTTP_REFERER", referer);
-	setenv1("HTTP_HOST", host); /* set to "" if NULL */
+	if (G.referer)
+		setenv1("HTTP_REFERER", G.referer);
+	setenv1("HTTP_HOST", G.host); /* set to "" if NULL */
 	/* setenv1("SERVER_NAME", safe_gethostname()); - don't do this,
 	 * just run "env SERVER_NAME=xyz httpd ..." instead */
 
@@ -2269,10 +2264,8 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
 #if ENABLE_FEATURE_HTTPD_PROXY
 			/* We need 2 more bytes for yet another "\r\n" -
 			 * see near fdprintf(proxy_fd...) further below */
-			if (proxy_entry && (header_ptr - header_buf) < IOBUF_SIZE - 2) {
-				int len = strlen(iobuf);
-				if (len > IOBUF_SIZE - (header_ptr - header_buf) - 4)
-					len = IOBUF_SIZE - (header_ptr - header_buf) - 4;
+			if (proxy_entry && (header_ptr - header_buf) < IOBUF_SIZE - 4) {
+				int len = strnlen(iobuf, IOBUF_SIZE - (header_ptr - header_buf) - 4);
 				memcpy(header_ptr, iobuf, len);
 				header_ptr += len;
 				header_ptr[0] = '\r';
@@ -2303,19 +2296,26 @@ static void handle_incoming_and_exit(const len_and_sockaddr *fromAddr)
 #endif
 #if ENABLE_FEATURE_HTTPD_CGI
 			else if (STRNCASECMP(iobuf, "Cookie:") == 0) {
-				cookie = xstrdup(skip_whitespace(iobuf + sizeof("Cookie:")-1));
+				if (!cookie) /* in case they send millions of these, do not OOM */
+					cookie = xstrdup(skip_whitespace(iobuf + sizeof("Cookie:")-1));
 			} else if (STRNCASECMP(iobuf, "Content-Type:") == 0) {
-				content_type = xstrdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1));
+				if (!content_type)
+					content_type = xstrdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1));
 			} else if (STRNCASECMP(iobuf, "Referer:") == 0) {
-				referer = xstrdup(skip_whitespace(iobuf + sizeof("Referer:")-1));
+				if (!G.referer)
+					G.referer = xstrdup(skip_whitespace(iobuf + sizeof("Referer:")-1));
 			} else if (STRNCASECMP(iobuf, "User-Agent:") == 0) {
-				user_agent = xstrdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1));
+				if (!G.user_agent)
+					G.user_agent = xstrdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1));
 			} else if (STRNCASECMP(iobuf, "Host:") == 0) {
-				host = xstrdup(skip_whitespace(iobuf + sizeof("Host:")-1));
+				if (!G.host)
+					G.host = xstrdup(skip_whitespace(iobuf + sizeof("Host:")-1));
 			} else if (STRNCASECMP(iobuf, "Accept:") == 0) {
-				http_accept = xstrdup(skip_whitespace(iobuf + sizeof("Accept:")-1));
+				if (!G.http_accept)
+					G.http_accept = xstrdup(skip_whitespace(iobuf + sizeof("Accept:")-1));
 			} else if (STRNCASECMP(iobuf, "Accept-Language:") == 0) {
-				http_accept_language = xstrdup(skip_whitespace(iobuf + sizeof("Accept-Language:")-1));
+				if (!G.http_accept_language)
+					G.http_accept_language = xstrdup(skip_whitespace(iobuf + sizeof("Accept-Language:")-1));
 			}
 #endif
 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH


More information about the busybox-cvs mailing list