diff -Nru apache2-2.4.7/debian/changelog apache2-2.4.7/debian/changelog --- apache2-2.4.7/debian/changelog 2014-07-21 19:53:59.000000000 +0000 +++ apache2-2.4.7/debian/changelog 2015-03-10 12:47:08.000000000 +0000 @@ -1,3 +1,29 @@ +apache2 (2.4.7-1ubuntu4.4) trusty-security; urgency=medium + + * SECURITY UPDATE: HTTP header replacement via HTTP trailers (LP: #1425141) + - debian/patches/CVE-2013-5704.patch: don't merge trailers by default + and add a "MergeTrailers" directive to revert to previous behaviour + to include/http_core.h, include/httpd.h, modules/http/http_filters.c, + modules/http/http_request.c, modules/loggers/mod_log_config.c, + modules/proxy/mod_proxy_http.c, server/core.c, server/protocol.c. + - CVE-2013-5704 + * SECURITY UPDATE: mod_cache denial of service via empty HTTP + Content-Type header + - debian/patches/CVE-2014-3581.patch: check for NULL in + modules/cache/cache_util.c. + - CVE-2014-3581 + + -- Marc Deslauriers Tue, 10 Mar 2015 07:42:50 -0400 + +apache2 (2.4.7-1ubuntu4.2) trusty; urgency=medium + + * d/p/ocsp-stapling-memory-corruption.patch: fix crash on startup due + to memory corruption while modules are reloaded (LP: #1366174). + Thanks to Alex Bligh for reporting, debugging, fixing upstream, + backporting and driving this fix through to Trusty. + + -- Robie Basak Thu, 26 Feb 2015 18:11:56 +0000 + apache2 (2.4.7-1ubuntu4.1) trusty-security; urgency=medium * SECURITY UPDATE: denial of service in mod_proxy diff -Nru apache2-2.4.7/debian/patches/CVE-2013-5704.patch apache2-2.4.7/debian/patches/CVE-2013-5704.patch --- apache2-2.4.7/debian/patches/CVE-2013-5704.patch 1970-01-01 00:00:00.000000000 +0000 +++ apache2-2.4.7/debian/patches/CVE-2013-5704.patch 2015-03-10 11:42:42.000000000 +0000 @@ -0,0 +1,414 @@ +From 6688f9d102ad29d6bb4167d690ee495d709e47b6 Mon Sep 17 00:00:00 2001 +From: "William A. Rowe Jr" +Date: Fri, 22 Aug 2014 18:18:08 +0000 +Subject: [PATCH] SECURITY: CVE-2013-5704 (cve.mitre.org) + +core: HTTP trailers could be used to replace HTTP headers +late during request processing, potentially undoing or +otherwise confusing modules that examined or modified +request headers earlier. Adds "MergeTrailers" directive to restore +legacy behavior. + +Submitted by: Edward Lu, Yann Ylavic, Joe Orton, Eric Covener +Backports: r1610814 +Reviewed by: covener, wrowe, ylavic + + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1619884 13f79535-47bb-0310-9956-ffa450edef68 +--- + CHANGES | 8 ++++- + docs/manual/mod/core.xml | 19 +++++++++++ + docs/manual/mod/mod_log_config.xml | 8 +++++ + include/ap_mmn.h | 3 +- + include/http_core.h | 4 +++ + include/httpd.h | 5 +++ + modules/http/http_filters.c | 65 ++++++++++++++++++++++++++++++-------- + modules/http/http_request.c | 4 +++ + modules/loggers/mod_log_config.c | 29 +++++++++++++++-- + modules/proxy/mod_proxy_http.c | 18 +++++++++++ + server/core.c | 17 +++++++++- + server/protocol.c | 6 ++++ + 12 files changed, 166 insertions(+), 20 deletions(-) + +Index: apache2-2.4.7/include/http_core.h +=================================================================== +--- apache2-2.4.7.orig/include/http_core.h 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/include/http_core.h 2015-03-05 12:29:19.557674382 -0500 +@@ -663,6 +663,10 @@ + #define AP_TRACE_ENABLE 1 + #define AP_TRACE_EXTENDED 2 + int trace_enable; ++#define AP_MERGE_TRAILERS_UNSET 0 ++#define AP_MERGE_TRAILERS_ENABLE 1 ++#define AP_MERGE_TRAILERS_DISABLE 2 ++ int merge_trailers; + + } core_server_config; + +Index: apache2-2.4.7/include/httpd.h +=================================================================== +--- apache2-2.4.7.orig/include/httpd.h 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/include/httpd.h 2015-03-05 12:29:19.557674382 -0500 +@@ -1032,6 +1032,11 @@ + */ + apr_sockaddr_t *useragent_addr; + char *useragent_ip; ++ ++ /** MIME trailer environment from the request */ ++ apr_table_t *trailers_in; ++ /** MIME trailer environment from the response */ ++ apr_table_t *trailers_out; + }; + + /** +Index: apache2-2.4.7/modules/http/http_filters.c +=================================================================== +--- apache2-2.4.7.orig/modules/http/http_filters.c 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/modules/http/http_filters.c 2015-03-05 12:29:19.557674382 -0500 +@@ -214,6 +214,49 @@ + } + + ++static apr_status_t read_chunked_trailers(http_ctx_t *ctx, ap_filter_t *f, ++ apr_bucket_brigade *b, int merge) ++{ ++ int rv; ++ apr_bucket *e; ++ request_rec *r = f->r; ++ apr_table_t *saved_headers_in = r->headers_in; ++ int saved_status = r->status; ++ ++ r->status = HTTP_OK; ++ r->headers_in = r->trailers_in; ++ apr_table_clear(r->headers_in); ++ ctx->state = BODY_NONE; ++ ap_get_mime_headers(r); ++ ++ if(r->status == HTTP_OK) { ++ r->status = saved_status; ++ e = apr_bucket_eos_create(f->c->bucket_alloc); ++ APR_BRIGADE_INSERT_TAIL(b, e); ++ ctx->eos_sent = 1; ++ rv = APR_SUCCESS; ++ } ++ else { ++ const char *error_notes = apr_table_get(r->notes, ++ "error-notes"); ++ ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r, ++ "Error while reading HTTP trailer: %i%s%s", ++ r->status, error_notes ? ": " : "", ++ error_notes ? error_notes : ""); ++ rv = APR_EINVAL; ++ } ++ ++ if(!merge) { ++ r->headers_in = saved_headers_in; ++ } ++ else { ++ r->headers_in = apr_table_overlay(r->pool, saved_headers_in, ++ r->trailers_in); ++ } ++ ++ return rv; ++} ++ + /* This is the HTTP_INPUT filter for HTTP requests and responses from + * proxied servers (mod_proxy). It handles chunked and content-length + * bodies. This can only be inserted/used after the headers +@@ -223,6 +266,7 @@ + ap_input_mode_t mode, apr_read_type_e block, + apr_off_t readbytes) + { ++ core_server_config *conf; + apr_bucket *e; + http_ctx_t *ctx = f->ctx; + apr_status_t rv; +@@ -230,6 +274,9 @@ + int http_error = HTTP_REQUEST_ENTITY_TOO_LARGE; + apr_bucket_brigade *bb; + ++ conf = (core_server_config *) ++ ap_get_module_config(f->r->server->module_config, &core_module); ++ + /* just get out of the way of things we don't want. */ + if (mode != AP_MODE_READBYTES && mode != AP_MODE_GETLINE) { + return ap_get_brigade(f->next, b, mode, block, readbytes); +@@ -403,13 +450,8 @@ + } + + if (!ctx->remaining) { +- /* Handle trailers by calling ap_get_mime_headers again! */ +- ctx->state = BODY_NONE; +- ap_get_mime_headers(f->r); +- e = apr_bucket_eos_create(f->c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(b, e); +- ctx->eos_sent = 1; +- return APR_SUCCESS; ++ return read_chunked_trailers(ctx, f, b, ++ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); + } + } + } +@@ -509,13 +551,8 @@ + } + + if (!ctx->remaining) { +- /* Handle trailers by calling ap_get_mime_headers again! */ +- ctx->state = BODY_NONE; +- ap_get_mime_headers(f->r); +- e = apr_bucket_eos_create(f->c->bucket_alloc); +- APR_BRIGADE_INSERT_TAIL(b, e); +- ctx->eos_sent = 1; +- return APR_SUCCESS; ++ return read_chunked_trailers(ctx, f, b, ++ conf->merge_trailers == AP_MERGE_TRAILERS_ENABLE); + } + } + break; +Index: apache2-2.4.7/modules/http/http_request.c +=================================================================== +--- apache2-2.4.7.orig/modules/http/http_request.c 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/modules/http/http_request.c 2015-03-05 12:29:19.561674411 -0500 +@@ -463,6 +463,7 @@ + new->main = r->main; + + new->headers_in = r->headers_in; ++ new->trailers_in = r->trailers_in; + new->headers_out = apr_table_make(r->pool, 12); + if (ap_is_HTTP_REDIRECT(new->status)) { + const char *location = apr_table_get(r->headers_out, "Location"); +@@ -470,6 +471,7 @@ + apr_table_setn(new->headers_out, "Location", location); + } + new->err_headers_out = r->err_headers_out; ++ new->trailers_out = apr_table_make(r->pool, 5); + new->subprocess_env = rename_original_env(r->pool, r->subprocess_env); + new->notes = apr_table_make(r->pool, 5); + +@@ -583,6 +585,8 @@ + r->headers_out); + r->err_headers_out = apr_table_overlay(r->pool, rr->err_headers_out, + r->err_headers_out); ++ r->trailers_out = apr_table_overlay(r->pool, rr->trailers_out, ++ r->trailers_out); + r->subprocess_env = apr_table_overlay(r->pool, rr->subprocess_env, + r->subprocess_env); + +Index: apache2-2.4.7/modules/loggers/mod_log_config.c +=================================================================== +--- apache2-2.4.7.orig/modules/loggers/mod_log_config.c 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/modules/loggers/mod_log_config.c 2015-03-05 12:29:19.561674411 -0500 +@@ -431,6 +431,12 @@ + return ap_escape_logitem(r->pool, apr_table_get(r->headers_in, a)); + } + ++static const char *log_trailer_in(request_rec *r, char *a) ++{ ++ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_in, a)); ++} ++ ++ + static APR_INLINE char *find_multiple_headers(apr_pool_t *pool, + const apr_table_t *table, + const char *key) +@@ -514,6 +520,11 @@ + return ap_escape_logitem(r->pool, cp); + } + ++static const char *log_trailer_out(request_rec *r, char *a) ++{ ++ return ap_escape_logitem(r->pool, apr_table_get(r->trailers_out, a)); ++} ++ + static const char *log_note(request_rec *r, char *a) + { + return ap_escape_logitem(r->pool, apr_table_get(r->notes, a)); +@@ -916,7 +927,7 @@ + static char *parse_log_item(apr_pool_t *p, log_format_item *it, const char **sa) + { + const char *s = *sa; +- ap_log_handler *handler; ++ ap_log_handler *handler = NULL; + + if (*s != '%') { + return parse_log_misc_string(p, it, sa); +@@ -986,7 +997,16 @@ + break; + + default: +- handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); ++ /* check for '^' + two character format first */ ++ if (*s == '^' && *(s+1) && *(s+2)) { ++ handler = (ap_log_handler *)apr_hash_get(log_hash, s, 3); ++ if (handler) { ++ s += 3; ++ } ++ } ++ if (!handler) { ++ handler = (ap_log_handler *)apr_hash_get(log_hash, s++, 1); ++ } + if (!handler) { + char dummy[2]; + +@@ -1516,7 +1536,7 @@ + log_struct->func = handler; + log_struct->want_orig_default = def; + +- apr_hash_set(log_hash, tag, 1, (const void *)log_struct); ++ apr_hash_set(log_hash, tag, strlen(tag), (const void *)log_struct); + } + static ap_log_writer_init *ap_log_set_writer_init(ap_log_writer_init *handle) + { +@@ -1694,6 +1714,9 @@ + log_pfn_register(p, "U", log_request_uri, 1); + log_pfn_register(p, "s", log_status, 1); + log_pfn_register(p, "R", log_handler, 1); ++ ++ log_pfn_register(p, "^ti", log_trailer_in, 0); ++ log_pfn_register(p, "^to", log_trailer_out, 0); + } + + /* reset to default conditions */ +Index: apache2-2.4.7/modules/proxy/mod_proxy_http.c +=================================================================== +--- apache2-2.4.7.orig/modules/proxy/mod_proxy_http.c 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/modules/proxy/mod_proxy_http.c 2015-03-05 12:29:19.561674411 -0500 +@@ -994,8 +994,11 @@ + rp->status = HTTP_OK; + + rp->headers_in = apr_table_make(pool, 50); ++ rp->trailers_in = apr_table_make(pool, 5); ++ + rp->subprocess_env = apr_table_make(pool, 50); + rp->headers_out = apr_table_make(pool, 12); ++ rp->trailers_out = apr_table_make(pool, 5); + rp->err_headers_out = apr_table_make(pool, 5); + rp->notes = apr_table_make(pool, 5); + +@@ -1076,6 +1079,7 @@ + psc = (proxy_server_conf *) ap_get_module_config(sconf, &proxy_module); + + r->headers_out = apr_table_make(r->pool, 20); ++ r->trailers_out = apr_table_make(r->pool, 5); + *pread_len = 0; + + /* +@@ -1206,6 +1210,14 @@ + #define AP_MAX_INTERIM_RESPONSES 10 + #endif + ++static int add_trailers(void *data, const char *key, const char *val) ++{ ++ if (val) { ++ apr_table_add((apr_table_t*)data, key, val); ++ } ++ return 1; ++} ++ + static + apr_status_t ap_proxy_http_process_response(apr_pool_t * p, request_rec *r, + proxy_conn_rec **backend_ptr, +@@ -1717,6 +1729,12 @@ + /* next time try a non-blocking read */ + mode = APR_NONBLOCK_READ; + ++ if (!apr_is_empty_table(backend->r->trailers_in)) { ++ apr_table_do(add_trailers, r->trailers_out, ++ backend->r->trailers_in, NULL); ++ apr_table_clear(backend->r->trailers_in); ++ } ++ + apr_brigade_length(bb, 0, &readbytes); + backend->worker->s->read += readbytes; + #if DEBUGGING +Index: apache2-2.4.7/server/core.c +=================================================================== +--- apache2-2.4.7.orig/server/core.c 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/server/core.c 2015-03-05 12:29:19.561674411 -0500 +@@ -519,6 +519,10 @@ + if (virt->error_log_req) + conf->error_log_req = virt->error_log_req; + ++ conf->merge_trailers = (virt->merge_trailers != AP_MERGE_TRAILERS_UNSET) ++ ? virt->merge_trailers ++ : base->merge_trailers; ++ + return conf; + } + +@@ -3866,6 +3870,16 @@ + } + + ++static const char *set_merge_trailers(cmd_parms *cmd, void *dummy, int arg) ++{ ++ core_server_config *conf = ap_get_module_config(cmd->server->module_config, ++ &core_module); ++ conf->merge_trailers = (arg ? AP_MERGE_TRAILERS_ENABLE : ++ AP_MERGE_TRAILERS_DISABLE); ++ ++ return NULL; ++} ++ + /* Note --- ErrorDocument will now work from .htaccess files. + * The AllowOverride of Fileinfo allows webmasters to turn it off + */ +@@ -4113,6 +4127,8 @@ + #endif + AP_INIT_TAKE1("TraceEnable", set_trace_enable, NULL, RSRC_CONF, + "'on' (default), 'off' or 'extended' to trace request body content"), ++AP_INIT_FLAG("MergeTrailers", set_merge_trailers, NULL, RSRC_CONF, ++ "merge request trailers into request headers or not"), + { NULL } + }; + +@@ -4195,7 +4211,6 @@ + + static int do_nothing(request_rec *r) { return OK; } + +- + static int core_override_type(request_rec *r) + { + core_dir_config *conf = +Index: apache2-2.4.7/server/protocol.c +=================================================================== +--- apache2-2.4.7.orig/server/protocol.c 2015-03-05 12:29:19.561674411 -0500 ++++ apache2-2.4.7/server/protocol.c 2015-03-05 12:29:19.561674411 -0500 +@@ -718,6 +718,8 @@ + r->status = HTTP_REQUEST_TIME_OUT; + } + else { ++ ap_log_rerror(APLOG_MARK, APLOG_DEBUG, rv, r, ++ "Failed to read request header line %s", field); + r->status = HTTP_BAD_REQUEST; + } + +@@ -917,9 +919,11 @@ + r->allowed_methods = ap_make_method_list(p, 2); + + r->headers_in = apr_table_make(r->pool, 25); ++ r->trailers_in = apr_table_make(r->pool, 5); + r->subprocess_env = apr_table_make(r->pool, 25); + r->headers_out = apr_table_make(r->pool, 12); + r->err_headers_out = apr_table_make(r->pool, 5); ++ r->trailers_out = apr_table_make(r->pool, 5); + r->notes = apr_table_make(r->pool, 5); + + r->request_config = ap_create_request_config(r->pool); +@@ -1161,6 +1165,7 @@ + rnew->status = HTTP_OK; + + rnew->headers_in = apr_table_copy(rnew->pool, r->headers_in); ++ rnew->trailers_in = apr_table_copy(rnew->pool, r->trailers_in); + + /* did the original request have a body? (e.g. POST w/SSI tags) + * if so, make sure the subrequest doesn't inherit body headers +@@ -1172,6 +1177,7 @@ + rnew->subprocess_env = apr_table_copy(rnew->pool, r->subprocess_env); + rnew->headers_out = apr_table_make(rnew->pool, 5); + rnew->err_headers_out = apr_table_make(rnew->pool, 5); ++ rnew->trailers_out = apr_table_make(rnew->pool, 5); + rnew->notes = apr_table_make(rnew->pool, 5); + + rnew->expecting_100 = r->expecting_100; diff -Nru apache2-2.4.7/debian/patches/CVE-2014-3581.patch apache2-2.4.7/debian/patches/CVE-2014-3581.patch --- apache2-2.4.7/debian/patches/CVE-2014-3581.patch 1970-01-01 00:00:00.000000000 +0000 +++ apache2-2.4.7/debian/patches/CVE-2014-3581.patch 2015-03-10 11:42:42.000000000 +0000 @@ -0,0 +1,43 @@ +Backport of: + +From c164ca7383d5f204915d85a5826655d3f1557148 Mon Sep 17 00:00:00 2001 +From: Jim Jagielski +Date: Fri, 26 Sep 2014 11:00:14 +0000 +Subject: [PATCH] Merge r1624234 from trunk: + +SECURITY (CVE-2014-3581): Fix a mod_cache NULL pointer deference +in Content-Type handling. + +mod_cache: Avoid a crash when Content-Type has an empty value. PR56924. + +Submitted By: Mark Montague +Reviewed By: Jan Kaluza + +Submitted by: jkaluza +Reviewed/backported by: jim + + +git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1627749 13f79535-47bb-0310-9956-ffa450edef68 +--- + CHANGES | 4 ++++ + STATUS | 5 ----- + modules/cache/cache_util.c | 6 ++++-- + 3 files changed, 8 insertions(+), 7 deletions(-) + +Index: apache2-2.4.7/modules/cache/cache_util.c +=================================================================== +--- apache2-2.4.7.orig/modules/cache/cache_util.c 2015-03-05 12:36:22.668840232 -0500 ++++ apache2-2.4.7/modules/cache/cache_util.c 2015-03-05 12:37:06.393173138 -0500 +@@ -1251,8 +1251,10 @@ + + if (!apr_table_get(headers_out, "Content-Type") + && r->content_type) { +- apr_table_setn(headers_out, "Content-Type", +- ap_make_content_type(r, r->content_type)); ++ const char *ctype = ap_make_content_type(r, r->content_type); ++ if (ctype) { ++ apr_table_setn(headers_out, "Content-Type", ctype); ++ } + } + + if (!apr_table_get(headers_out, "Content-Encoding") diff -Nru apache2-2.4.7/debian/patches/ocsp-stapling-memory-corruption.patch apache2-2.4.7/debian/patches/ocsp-stapling-memory-corruption.patch --- apache2-2.4.7/debian/patches/ocsp-stapling-memory-corruption.patch 1970-01-01 00:00:00.000000000 +0000 +++ apache2-2.4.7/debian/patches/ocsp-stapling-memory-corruption.patch 2015-02-26 18:07:26.000000000 +0000 @@ -0,0 +1,316 @@ +From 6e24e496c7aee8aa1ff13a41dae71c91fe8c0bbe Mon Sep 17 00:00:00 2001 +From: Alex Bligh +Date: Thu, 6 Nov 2014 20:37:42 +0000 +Subject: [PATCH] LP#1366174: Backport PR54357 to 2.4.7 - Crash during restart + or at startup in mod_ssl, in certinfo_free() function registered by + ssl_stapling_ex_init() + +Backport SVN: + https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1634529 +details of which follow: + +Merge r1629372, r1629485, r1629519 from trunk: + +Move OCSP stapling information from a per-certificate store +(ex_data attached to an X509 *) to a per-server hash which is +allocated from the pconf pool. Fixes PR 54357, PR 56919 and +a leak with the certinfo_free cleanup function (missing +OCSP_CERTID_free). + +* modules/ssl/ssl_util_stapling.c: drop certinfo_free, and add + ssl_stapling_certid_free (used with apr_pool_cleanup_register). + Switch to a stapling_certinfo hash which is keyed by the SHA-1 + digest of the certificate's DER encoding, rework ssl_stapling_init_cert + to only store info once per certificate (allocated from the pconf + to the extent possible) and extend the logging. + +* modules/ssl/ssl_private.h: adjust prototype for + ssl_stapling_init_cert, replace ssl_stapling_ex_init with + ssl_stapling_certinfo_hash_init + +* modules/ssl/ssl_engine_init.c: adjust ssl_stapling_* calls + +Based on initial work by Alex Bligh + +Follow up to r1629372: ensure compatibily with OpenSSL < 1.0 (sk_OPENSSL_STRING_value). + +Follow up to r1629372 and r1629485: ensure compatibily with OpenSSL < 1.0 (sk_OPENSSL_STRING_[num|value|pop] macros). +Submitted by: kbrand, ylavic, ylavic +Reviewed/backported by: jim + +Origin: backport, https://svn.apache.org/viewvc?view=revision&revision=r1634529 +Bug: https://bz.apache.org/bugzilla/show_bug.cgi?id=54357 +Bug-Ubuntu: https://launchpad.net/bugs/1366174 +Reviewed-by: Robie Basak +Last-Update: 2015-02-26 + +--- a/modules/ssl/ssl_engine_init.c ++++ b/modules/ssl/ssl_engine_init.c +@@ -200,7 +200,7 @@ + return HTTP_INTERNAL_SERVER_ERROR; + } + #ifdef HAVE_OCSP_STAPLING +- ssl_stapling_ex_init(); ++ ssl_stapling_certinfo_hash_init(p); + #endif + + /* +@@ -818,6 +818,8 @@ + } + + static int ssl_server_import_cert(server_rec *s, ++ apr_pool_t *p, ++ apr_pool_t *ptemp, + modssl_ctx_t *mctx, + const char *id, + int idx) +@@ -852,7 +854,7 @@ + + #ifdef HAVE_OCSP_STAPLING + if ((mctx->pkp == FALSE) && (mctx->stapling_enabled == TRUE)) { +- if (!ssl_stapling_init_cert(s, mctx, cert)) { ++ if (!ssl_stapling_init_cert(s, p, ptemp, mctx, cert)) { + ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02235) + "Unable to configure server certificate for stapling"); + } +@@ -1000,10 +1002,10 @@ + ecc_id = ssl_asn1_table_keyfmt(ptemp, vhost_id, SSL_AIDX_ECC); + #endif + +- have_rsa = ssl_server_import_cert(s, mctx, rsa_id, SSL_AIDX_RSA); +- have_dsa = ssl_server_import_cert(s, mctx, dsa_id, SSL_AIDX_DSA); ++ have_rsa = ssl_server_import_cert(s, p, ptemp, mctx, rsa_id, SSL_AIDX_RSA); ++ have_dsa = ssl_server_import_cert(s, p, ptemp, mctx, dsa_id, SSL_AIDX_DSA); + #ifdef HAVE_ECC +- have_ecc = ssl_server_import_cert(s, mctx, ecc_id, SSL_AIDX_ECC); ++ have_ecc = ssl_server_import_cert(s, p, ptemp, mctx, ecc_id, SSL_AIDX_ECC); + #endif + + if (!(have_rsa || have_dsa +--- a/modules/ssl/ssl_private.h ++++ b/modules/ssl/ssl_private.h +@@ -147,6 +147,13 @@ + /* OCSP stapling */ + #if !defined(OPENSSL_NO_OCSP) && defined(SSL_CTX_set_tlsext_status_cb) + #define HAVE_OCSP_STAPLING ++/* backward compatibility with OpenSSL < 1.0 */ ++#ifndef sk_OPENSSL_STRING_num ++#define sk_OPENSSL_STRING_num sk_num ++#endif ++#ifndef sk_OPENSSL_STRING_value ++#define sk_OPENSSL_STRING_value sk_value ++#endif + #ifndef sk_OPENSSL_STRING_pop + #define sk_OPENSSL_STRING_pop sk_pop + #endif +@@ -826,10 +833,11 @@ + const char *ssl_cmd_SSLStaplingReturnResponderErrors(cmd_parms *, void *, int); + const char *ssl_cmd_SSLStaplingFakeTryLater(cmd_parms *, void *, int); + const char *ssl_cmd_SSLStaplingResponderTimeout(cmd_parms *, void *, const char *); +-const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *); ++const char *ssl_cmd_SSLStaplingForceURL(cmd_parms *, void *, const char *); + void modssl_init_stapling(server_rec *, apr_pool_t *, apr_pool_t *, modssl_ctx_t *); +-void ssl_stapling_ex_init(void); +-int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x); ++void ssl_stapling_certinfo_hash_init(apr_pool_t *); ++int ssl_stapling_init_cert(server_rec *s, apr_pool_t *, apr_pool_t *, ++ modssl_ctx_t *mctx, X509 *x); + #endif + #ifdef HAVE_SRP + int ssl_callback_SRPServerParams(SSL *, int *, void *); +--- a/modules/ssl/ssl_util_stapling.c ++++ b/modules/ssl/ssl_util_stapling.c +@@ -43,36 +43,32 @@ + + #define MAX_STAPLING_DER 10240 + +-/* Cached info stored in certificate ex_info. */ ++/* Cached info stored in the global stapling_certinfo hash. */ + typedef struct { +- /* Index in session cache SHA1 hash of certificate */ +- UCHAR idx[20]; +- /* Certificate ID for OCSP requests or NULL if ID cannot be determined */ ++ /* Index in session cache (SHA-1 digest of DER encoded certificate) */ ++ UCHAR idx[SHA_DIGEST_LENGTH]; ++ /* Certificate ID for OCSP request */ + OCSP_CERTID *cid; +- /* Responder details */ ++ /* URI of the OCSP responder */ + char *uri; + } certinfo; + +-static void certinfo_free(void *parent, void *ptr, CRYPTO_EX_DATA *ad, +- int idx, long argl, void *argp) ++static apr_status_t ssl_stapling_certid_free(void *data) + { +- certinfo *cinf = ptr; ++ OCSP_CERTID *cid = data; + +- if (!cinf) +- return; +- if (cinf->uri) +- OPENSSL_free(cinf->uri); +- OPENSSL_free(cinf); ++ if (cid) { ++ OCSP_CERTID_free(cid); ++ } ++ ++ return APR_SUCCESS; + } + +-static int stapling_ex_idx = -1; ++static apr_hash_t *stapling_certinfo; + +-void ssl_stapling_ex_init(void) ++void ssl_stapling_certinfo_hash_init(apr_pool_t *p) + { +- if (stapling_ex_idx != -1) +- return; +- stapling_ex_idx = X509_get_ex_new_index(0, "X509 cached OCSP info", 0, 0, +- certinfo_free); ++ stapling_certinfo = apr_hash_make(p); + } + + static X509 *stapling_get_issuer(modssl_ctx_t *mctx, X509 *x) +@@ -106,69 +102,96 @@ + + } + +-int ssl_stapling_init_cert(server_rec *s, modssl_ctx_t *mctx, X509 *x) ++int ssl_stapling_init_cert(server_rec *s, apr_pool_t *p, apr_pool_t *ptemp, ++ modssl_ctx_t *mctx, X509 *x) + { +- certinfo *cinf; ++ UCHAR idx[SHA_DIGEST_LENGTH]; ++ certinfo *cinf = NULL; + X509 *issuer = NULL; ++ OCSP_CERTID *cid = NULL; + STACK_OF(OPENSSL_STRING) *aia = NULL; + +- if (x == NULL) ++ if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1)) + return 0; +- cinf = X509_get_ex_data(x, stapling_ex_idx); ++ ++ cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx)); + if (cinf) { +- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02215) +- "ssl_stapling_init_cert: certificate already initialized!"); +- return 0; +- } +- cinf = OPENSSL_malloc(sizeof(certinfo)); +- if (!cinf) { +- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02216) +- "ssl_stapling_init_cert: error allocating memory!"); +- return 0; ++ /* ++ * We already parsed the certificate, and no OCSP URI was found. ++ * The certificate might be used for multiple vhosts, though, ++ * so we check for a ForceURL for this vhost. ++ */ ++ if (!cinf->uri && !mctx->stapling_force_url) { ++ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, ++ APLOGNO(02814) "ssl_stapling_init_cert: no OCSP URI " ++ "in certificate and no SSLStaplingForceURL " ++ "configured for server %s", mctx->sc->vhost_id); ++ return 0; ++ } ++ return 1; + } +- cinf->cid = NULL; +- cinf->uri = NULL; +- X509_set_ex_data(x, stapling_ex_idx, cinf); +- +- issuer = stapling_get_issuer(mctx, x); +- +- if (issuer == NULL) { +- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02217) +- "ssl_stapling_init_cert: Can't retrieve issuer certificate!"); ++ ++ if (!(issuer = stapling_get_issuer(mctx, x))) { ++ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02217) ++ "ssl_stapling_init_cert: can't retrieve issuer " ++ "certificate!"); + return 0; + } + +- cinf->cid = OCSP_cert_to_id(NULL, x, issuer); ++ cid = OCSP_cert_to_id(NULL, x, issuer); + X509_free(issuer); +- if (!cinf->cid) ++ if (!cid) { ++ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, APLOGNO(02815) ++ "ssl_stapling_init_cert: can't create CertID " ++ "for OCSP request"); + return 0; +- X509_digest(x, EVP_sha1(), cinf->idx, NULL); ++ } + + aia = X509_get1_ocsp(x); +- if (aia) +- cinf->uri = sk_OPENSSL_STRING_pop(aia); +- if (!cinf->uri && !mctx->stapling_force_url) { +- ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(02218) +- "ssl_stapling_init_cert: no responder URL"); ++ if (!aia && !mctx->stapling_force_url) { ++ OCSP_CERTID_free(cid); ++ ssl_log_xerror(SSLLOG_MARK, APLOG_ERR, 0, ptemp, s, x, ++ APLOGNO(02218) "ssl_stapling_init_cert: no OCSP URI " ++ "in certificate and no SSLStaplingForceURL set"); ++ return 0; + } +- if (aia) ++ ++ /* At this point, we have determined that there's something to store */ ++ cinf = apr_pcalloc(p, sizeof(certinfo)); ++ memcpy (cinf->idx, idx, sizeof(idx)); ++ cinf->cid = cid; ++ /* make sure cid is also freed at pool cleanup */ ++ apr_pool_cleanup_register(p, cid, ssl_stapling_certid_free, ++ apr_pool_cleanup_null); ++ if (aia) { ++ /* allocate uri from the pconf pool */ ++ cinf->uri = apr_pstrdup(p, sk_OPENSSL_STRING_value(aia, 0)); + X509_email_free(aia); ++ } ++ ++ ssl_log_xerror(SSLLOG_MARK, APLOG_TRACE1, 0, ptemp, s, x, ++ "ssl_stapling_init_cert: storing certinfo for server %s", ++ mctx->sc->vhost_id); ++ ++ apr_hash_set(stapling_certinfo, cinf->idx, sizeof(cinf->idx), cinf); ++ + return 1; + } + +-static certinfo *stapling_get_cert_info(server_rec *s, modssl_ctx_t *mctx, +- SSL *ssl) ++static certinfo *stapling_get_certinfo(server_rec *s, modssl_ctx_t *mctx, ++ SSL *ssl) + { + certinfo *cinf; + X509 *x; ++ UCHAR idx[SHA_DIGEST_LENGTH]; + x = SSL_get_certificate(ssl); +- if (x == NULL) ++ if ((x == NULL) || (X509_digest(x, EVP_sha1(), idx, NULL) != 1)) + return NULL; +- cinf = X509_get_ex_data(x, stapling_ex_idx); ++ cinf = apr_hash_get(stapling_certinfo, idx, sizeof(idx)); + if (cinf && cinf->cid) + return cinf; + ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01926) +- "stapling_get_cert_info: stapling not supported for certificate"); ++ "stapling_get_certinfo: stapling not supported for certificate"); + return NULL; + } + +@@ -577,7 +600,7 @@ + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, s, APLOGNO(01951) + "stapling_cb: OCSP Stapling callback called"); + +- cinf = stapling_get_cert_info(s, mctx, ssl); ++ cinf = stapling_get_certinfo(s, mctx, ssl); + if (cinf == NULL) { + return SSL_TLSEXT_ERR_NOACK; + } diff -Nru apache2-2.4.7/debian/patches/series apache2-2.4.7/debian/patches/series --- apache2-2.4.7/debian/patches/series 2014-07-21 19:45:30.000000000 +0000 +++ apache2-2.4.7/debian/patches/series 2015-03-10 11:43:31.000000000 +0000 @@ -15,3 +15,6 @@ CVE-2014-0118.patch CVE-2014-0226.patch CVE-2014-0231.patch +ocsp-stapling-memory-corruption.patch +CVE-2013-5704.patch +CVE-2014-3581.patch