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>
This commit is contained in:
Denys Vlasenko 2017-01-26 19:35:40 +01:00
parent 4d417709b0
commit b4b12bf234

View File

@ -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