diff options
Diffstat (limited to 'meta-webserver/recipes-httpd/apache2/apache2/apache-CVE-2014-0117.patch')
-rw-r--r-- | meta-webserver/recipes-httpd/apache2/apache2/apache-CVE-2014-0117.patch | 289 |
1 files changed, 0 insertions, 289 deletions
diff --git a/meta-webserver/recipes-httpd/apache2/apache2/apache-CVE-2014-0117.patch b/meta-webserver/recipes-httpd/apache2/apache2/apache-CVE-2014-0117.patch deleted file mode 100644 index 8585f0bb30..0000000000 --- a/meta-webserver/recipes-httpd/apache2/apache2/apache-CVE-2014-0117.patch +++ /dev/null @@ -1,289 +0,0 @@ -apache: CVE-2014-0117 - -The patch comes from upstream: -http://svn.apache.org/viewvc?view=revision&revision=1610674 - -SECURITY (CVE-2014-0117): Fix a crash in mod_proxy. In a -reverse proxy configuration, a remote attacker could send a carefully crafted -request which could crash a server process, resulting in denial of service. - -Thanks to Marek Kroemeke working with HP's Zero Day Initiative for -reporting this issue. - -Upstream-Status: Backport - -Submitted by: Edward Lu, breser, covener -Signed-off-by: Zhang Xiao <xiao.zhang@windriver.com> ---- - modules/proxy/mod_proxy_http.c | 8 +++- - include/httpd.h | 17 ++++++++ - modules/proxy/proxy_util.c | 67 ++++++++++++++---------------- - server/util.c | 89 ++++++++++++++++++++++++++++++++++++++++++ - 4 files changed, 143 insertions(+), 38 deletions(-) - -diff --git a/modules/proxy/mod_proxy_http.c b/modules/proxy/mod_proxy_http.c -index cffad2e..f11c16f 100644 ---- a/modules/proxy/mod_proxy_http.c -+++ b/modules/proxy/mod_proxy_http.c -@@ -1362,6 +1362,7 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, - */ - if (apr_date_checkmask(buffer, "HTTP/#.# ###*")) { - int major, minor; -+ int toclose; - - major = buffer[5] - '0'; - minor = buffer[7] - '0'; -@@ -1470,7 +1471,12 @@ apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, - te = apr_table_get(r->headers_out, "Transfer-Encoding"); - - /* strip connection listed hop-by-hop headers from response */ -- backend->close = ap_proxy_clear_connection_fn(r, r->headers_out); -+ toclose = ap_proxy_clear_connection_fn(r, r->headers_out); -+ backend->close = (toclose != 0); -+ if (toclose < 0) { -+ return ap_proxyerror(r, HTTP_BAD_REQUEST, -+ "Malformed connection header"); -+ } - - if ((buf = apr_table_get(r->headers_out, "Content-Type"))) { - ap_set_content_type(r, apr_pstrdup(p, buf)); -diff --git a/include/httpd.h b/include/httpd.h -index 36cd58d..9a2cf5c 100644 ---- a/include/httpd.h -+++ b/include/httpd.h -@@ -1528,6 +1528,23 @@ AP_DECLARE(int) ap_find_etag_weak(apr_pool_t *p, const char *line, const char *t - AP_DECLARE(int) ap_find_etag_strong(apr_pool_t *p, const char *line, const char *tok); - - /** -+ * Retrieve an array of tokens in the format "1#token" defined in RFC2616. Only -+ * accepts ',' as a delimiter, does not accept quoted strings, and errors on -+ * any separator. -+ * @param p The pool to allocate from -+ * @param tok The line to read tokens from -+ * @param tokens Pointer to an array of tokens. If not NULL, must be an array -+ * of char*, otherwise it will be allocated on @a p when a token is found -+ * @param skip_invalid If true, when an invalid separator is encountered, it -+ * will be ignored. -+ * @return NULL on success, an error string otherwise. -+ * @remark *tokens may be NULL on output if NULL in input and no token is found -+ */ -+AP_DECLARE(const char *) ap_parse_token_list_strict(apr_pool_t *p, const char *tok, -+ apr_array_header_t **tokens, -+ int skip_invalid); -+ -+/** - * Retrieve a token, spacing over it and adjusting the pointer to - * the first non-white byte afterwards. Note that these tokens - * are delimited by semis and commas and can also be delimited -diff --git a/modules/proxy/proxy_util.c b/modules/proxy/proxy_util.c -index 67dc939..58daa21 100644 ---- a/modules/proxy/proxy_util.c -+++ b/modules/proxy/proxy_util.c -@@ -2847,68 +2847,59 @@ PROXY_DECLARE(proxy_balancer_shared *) ap_proxy_find_balancershm(ap_slotmem_prov - typedef struct header_connection { - apr_pool_t *pool; - apr_array_header_t *array; -- const char *first; -- unsigned int closed:1; -+ const char *error; -+ int is_req; - } header_connection; - - static int find_conn_headers(void *data, const char *key, const char *val) - { - header_connection *x = data; -- const char *name; -- -- do { -- while (*val == ',' || *val == ';') { -- val++; -- } -- name = ap_get_token(x->pool, &val, 0); -- if (!strcasecmp(name, "close")) { -- x->closed = 1; -- } -- if (!x->first) { -- x->first = name; -- } -- else { -- const char **elt; -- if (!x->array) { -- x->array = apr_array_make(x->pool, 4, sizeof(char *)); -- } -- elt = apr_array_push(x->array); -- *elt = name; -- } -- } while (*val); - -- return 1; -+ x->error = ap_parse_token_list_strict(x->pool, val, &x->array, !x->is_req); -+ return !x->error; - } - - /** - * Remove all headers referred to by the Connection header. -+ * Returns -1 on error. Otherwise, returns 1 if 'Close' was seen in -+ * the Connection header tokens, and 0 if not. - */ - static int ap_proxy_clear_connection(request_rec *r, apr_table_t *headers) - { -- const char **name; -+ int closed = 0; - header_connection x; - - x.pool = r->pool; - x.array = NULL; -- x.first = NULL; -- x.closed = 0; -+ x.error = NULL; -+ x.is_req = (headers == r->headers_in); - - apr_table_unset(headers, "Proxy-Connection"); - - apr_table_do(find_conn_headers, &x, headers, "Connection", NULL); -- if (x.first) { -- /* fast path - no memory allocated for one header */ -- apr_table_unset(headers, "Connection"); -- apr_table_unset(headers, x.first); -+ apr_table_unset(headers, "Connection"); -+ -+ if (x.error) { -+ ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r, APLOGNO() -+ "Error parsing Connection header: %s", x.error); -+ return -1; - } -+ - if (x.array) { -- /* two or more headers */ -- while ((name = apr_array_pop(x.array))) { -- apr_table_unset(headers, *name); -+ int i; -+ for (i = 0; i < x.array->nelts; i++) { -+ const char *name = APR_ARRAY_IDX(x.array, i, const char *); -+ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r, APLOGNO() -+ "Removing header '%s' listed in Connection header", -+ name); -+ if (!strcasecmp(name, "close")) { -+ closed = 1; -+ } -+ apr_table_unset(headers, name); - } - } - -- return x.closed; -+ return closed; - } - - PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, -@@ -3095,7 +3086,9 @@ PROXY_DECLARE(int) ap_proxy_create_hdrbrgd(apr_pool_t *p, - * apr is compiled with APR_POOL_DEBUG. - */ - headers_in_copy = apr_table_copy(r->pool, r->headers_in); -- ap_proxy_clear_connection(r, headers_in_copy); -+ if (ap_proxy_clear_connection(r, headers_in_copy) < 0) { -+ return HTTP_BAD_REQUEST; -+ } - /* send request headers */ - headers_in_array = apr_table_elts(headers_in_copy); - headers_in = (const apr_table_entry_t *) headers_in_array->elts; -diff --git a/server/util.c b/server/util.c -index e0ba5c2..541c9f0 100644 ---- a/server/util.c -+++ b/server/util.c -@@ -1449,6 +1449,95 @@ AP_DECLARE(int) ap_find_etag_weak(apr_pool_t *p, const char *line, - return find_list_item(p, line, tok, AP_ETAG_WEAK); - } - -+/* Grab a list of tokens of the format 1#token (from RFC7230) */ -+AP_DECLARE(const char *) ap_parse_token_list_strict(apr_pool_t *p, -+ const char *str_in, -+ apr_array_header_t **tokens, -+ int skip_invalid) -+{ -+ int in_leading_space = 1; -+ int in_trailing_space = 0; -+ int string_end = 0; -+ const char *tok_begin; -+ const char *cur; -+ -+ if (!str_in) { -+ return NULL; -+ } -+ -+ tok_begin = cur = str_in; -+ -+ while (!string_end) { -+ const unsigned char c = (unsigned char)*cur; -+ -+ if (!TEST_CHAR(c, T_HTTP_TOKEN_STOP) && c != '\0') { -+ /* Non-separator character; we are finished with leading -+ * whitespace. We must never have encountered any trailing -+ * whitespace before the delimiter (comma) */ -+ in_leading_space = 0; -+ if (in_trailing_space) { -+ return "Encountered illegal whitespace in token"; -+ } -+ } -+ else if (c == ' ' || c == '\t') { -+ /* "Linear whitespace" only includes ASCII CRLF, space, and tab; -+ * we can't get a CRLF since headers are split on them already, -+ * so only look for a space or a tab */ -+ if (in_leading_space) { -+ /* We're still in leading whitespace */ -+ ++tok_begin; -+ } -+ else { -+ /* We must be in trailing whitespace */ -+ ++in_trailing_space; -+ } -+ } -+ else if (c == ',' || c == '\0') { -+ if (!in_leading_space) { -+ /* If we're out of the leading space, we know we've read some -+ * characters of a token */ -+ if (*tokens == NULL) { -+ *tokens = apr_array_make(p, 4, sizeof(char *)); -+ } -+ APR_ARRAY_PUSH(*tokens, char *) = -+ apr_pstrmemdup((*tokens)->pool, tok_begin, -+ (cur - tok_begin) - in_trailing_space); -+ } -+ /* We're allowed to have null elements, just don't add them to the -+ * array */ -+ -+ tok_begin = cur + 1; -+ in_leading_space = 1; -+ in_trailing_space = 0; -+ string_end = (c == '\0'); -+ } -+ else { -+ /* Encountered illegal separator char */ -+ if (skip_invalid) { -+ /* Skip to the next separator */ -+ const char *temp; -+ temp = ap_strchr_c(cur, ','); -+ if(!temp) { -+ temp = ap_strchr_c(cur, '\0'); -+ } -+ -+ /* Act like we haven't seen a token so we reset */ -+ cur = temp - 1; -+ in_leading_space = 1; -+ in_trailing_space = 0; -+ } -+ else { -+ return apr_psprintf(p, "Encountered illegal separator " -+ "'\\x%.2x'", (unsigned int)c); -+ } -+ } -+ -+ ++cur; -+ } -+ -+ return NULL; -+} -+ - /* Retrieve a token, spacing over it and returning a pointer to - * the first non-white byte afterwards. Note that these tokens - * are delimited by semis and commas; and can also be delimited --- |