[asterisk-commits] rmudgett: branch certified-1.8.15 r410427 - in /certified/branches/1.8.15: ./...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Mar 10 12:30:14 CDT 2014
Author: rmudgett
Date: Mon Mar 10 12:30:09 2014
New Revision: 410427
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=410427
Log:
Multiple revisions 394899,410380
........
r394899 | mjordan | 2013-07-20 22:09:16 -0500 (Sat, 20 Jul 2013) | 20 lines
Tolerate presence of RFC2965 Cookie2 header by ignoring it
This patch modifies parsing of cookies in Asterisk's http server by doing an
explicit comparison of the "Cookie" header instead of looking at the first
6 characters to determine if the header is a cookie header. This avoids
parsing "Cookie2" headers and overwriting the previously parsed "Cookie"
header.
Note that we probably should be appending the cookies in each "Cookie"
header to the parsed results; however, while clients can send multiple
cookie headers they never really do. While this patch doesn't improve
Asterisk's behavior in that regard, it shouldn't make it any worse either.
Note that the solution in this patch was pointed out on the issue by the
issue reporter, Stuart Henderson.
(closes issue ASTERISK-21789)
Reported by: Stuart Henderson
Tested by: mjordan, Stuart Henderson
........
r410380 | rmudgett | 2014-03-10 12:00:32 -0500 (Mon, 10 Mar 2014) | 11 lines
AST-2014-001: Stack overflow in HTTP processing of Cookie headers.
Sending a HTTP request that is handled by Asterisk with a large number of
Cookie headers could overflow the stack.
Another vulnerability along similar lines is any HTTP request with a
ridiculous number of headers in the request could exhaust system memory.
(closes issue ASTERISK-23340)
Reported by: Lucas Molas, researcher at Programa STIC, Fundacion; and Dr. Manuel Sadosky, Buenos Aires, Argentina
........
Merged revisions 394899,410380 from http://svn.asterisk.org/svn/asterisk/branches/1.8
Modified:
certified/branches/1.8.15/ (props changed)
certified/branches/1.8.15/main/http.c
Propchange: certified/branches/1.8.15/
------------------------------------------------------------------------------
Binary property 'branch-1.8-merged' - no diff available.
Modified: certified/branches/1.8.15/main/http.c
URL: http://svnview.digium.com/svn/asterisk/certified/branches/1.8.15/main/http.c?view=diff&rev=410427&r1=410426&r2=410427
==============================================================================
--- certified/branches/1.8.15/main/http.c (original)
+++ certified/branches/1.8.15/main/http.c Mon Mar 10 12:30:09 2014
@@ -187,9 +187,7 @@
break;
}
}
- if (cookies) {
- ast_variables_destroy(cookies);
- }
+ ast_variables_destroy(cookies);
return mngid;
}
@@ -683,7 +681,7 @@
prev = v;
}
}
-
+
done:
ast_free(buf);
return post_vars;
@@ -822,12 +820,13 @@
}*/
#endif /* DO_SSL */
-static struct ast_variable *parse_cookies(char *cookies)
-{
+static struct ast_variable *parse_cookies(const char *cookies)
+{
+ char *parse = ast_strdupa(cookies);
char *cur;
struct ast_variable *vars = NULL, *var;
- while ((cur = strsep(&cookies, ";"))) {
+ while ((cur = strsep(&parse, ";"))) {
char *name, *val;
name = val = cur;
@@ -857,21 +856,19 @@
/* get cookie from Request headers */
struct ast_variable *ast_http_get_cookies(struct ast_variable *headers)
{
- struct ast_variable *v, *cookies=NULL;
+ struct ast_variable *v, *cookies = NULL;
for (v = headers; v; v = v->next) {
- if (!strncasecmp(v->name, "Cookie", 6)) {
- char *tmp = ast_strdupa(v->value);
- if (cookies) {
- ast_variables_destroy(cookies);
- }
-
- cookies = parse_cookies(tmp);
+ if (!strcasecmp(v->name, "Cookie")) {
+ ast_variables_destroy(cookies);
+ cookies = parse_cookies(v->value);
}
}
return cookies;
}
+/*! Limit the number of request headers in case the sender is being ridiculous. */
+#define MAX_HTTP_REQUEST_HEADERS 100
static void *httpd_helper_thread(void *data)
{
@@ -882,6 +879,7 @@
struct ast_variable *tail = headers;
char *uri, *method;
enum ast_http_method http_method = AST_HTTP_UNKNOWN;
+ int remaining_headers;
if (ast_atomic_fetchadd_int(&session_count, +1) >= session_limit) {
goto done;
@@ -916,9 +914,13 @@
if (*c) {
*c = '\0';
}
+ } else {
+ ast_http_error(ser, 400, "Bad Request", "Invalid Request");
+ goto done;
}
/* process "Request Headers" lines */
+ remaining_headers = MAX_HTTP_REQUEST_HEADERS;
while (fgets(header_line, sizeof(header_line), ser->f)) {
char *name, *value;
@@ -941,6 +943,11 @@
ast_trim_blanks(name);
+ if (!remaining_headers--) {
+ /* Too many headers. */
+ ast_http_error(ser, 413, "Request Entity Too Large", "Too many headers");
+ goto done;
+ }
if (!headers) {
headers = ast_variable_new(name, value, __FILE__);
tail = headers;
@@ -948,11 +955,17 @@
tail->next = ast_variable_new(name, value, __FILE__);
tail = tail->next;
}
- }
-
- if (!*uri) {
- ast_http_error(ser, 400, "Bad Request", "Invalid Request");
- goto done;
+ if (!tail) {
+ /*
+ * Variable allocation failure.
+ * Try to make some room.
+ */
+ ast_variables_destroy(headers);
+ headers = NULL;
+
+ ast_http_error(ser, 500, "Server Error", "Out of memory");
+ goto done;
+ }
}
handle_uri(ser, uri, http_method, headers);
@@ -961,9 +974,7 @@
ast_atomic_fetchadd_int(&session_count, -1);
/* clean up all the header information */
- if (headers) {
- ast_variables_destroy(headers);
- }
+ ast_variables_destroy(headers);
if (ser->f) {
fclose(ser->f);
More information about the asterisk-commits
mailing list