diff options
author | Denys Vlasenko | 2017-01-26 19:35:40 +0100 |
---|---|---|
committer | Denys Vlasenko | 2017-01-26 19:35:40 +0100 |
commit | b4b12bf2344148976d1cd0f17bca0c0fbf7a364c (patch) | |
tree | a04afb20458db1c5138928e5dc0ad832a6de00de | |
parent | 4d417709b0fb837fd6884a9bc5a55027dec8a985 (diff) | |
download | busybox-b4b12bf2344148976d1cd0f17bca0c0fbf7a364c.zip busybox-b4b12bf2344148976d1cd0f17bca0c0fbf7a364c.tar.gz |
httpd: defend against attempts to OOM us. Closes 9611
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@googlemail.com>
-rw-r--r-- | networking/httpd.c | 48 |
1 files 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 |