[apache2] 02/03: CVE-2016-2161: mod_auth_digest: Fix segfaults
Stefan Fritsch
sf at moszumanska.debian.org
Sat Jan 21 22:05:25 UTC 2017
This is an automated email from the git hooks/post-receive script.
sf pushed a commit to branch jessie
in repository apache2.
commit 66276c67ad1845c7583ed9d3169cea831311e0c2
Author: Stefan Fritsch <sf at sfritsch.de>
Date: Sat Jan 21 22:15:00 2017 +0100
CVE-2016-2161: mod_auth_digest: Fix segfaults
---
debian/changelog | 2 +
.../CVE-2016-2161-mod_auth_digest_segfault.diff | 119 +++++++++++++++++++++
debian/patches/series | 1 +
3 files changed, 122 insertions(+)
diff --git a/debian/changelog b/debian/changelog
index e5c3f1c..5de448e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,5 +1,7 @@
apache2 (2.4.10-10+deb8u8) UNRELEASED; urgency=medium
+ * CVE-2016-2161: mod_auth_digest: Prevent segfaults when the shared memory
+ space is exhausted.
* Activate mod_reqtimeout in new installs and during updates from
before 2.4.10-10+deb8u8. It was wrongly not activated in new installs
since jessie. This made the default installation vulnerable to some
diff --git a/debian/patches/CVE-2016-2161-mod_auth_digest_segfault.diff b/debian/patches/CVE-2016-2161-mod_auth_digest_segfault.diff
new file mode 100644
index 0000000..4130b68
--- /dev/null
+++ b/debian/patches/CVE-2016-2161-mod_auth_digest_segfault.diff
@@ -0,0 +1,119 @@
+# https://svn.apache.org/r1773069
+--- apache2.orig/modules/aaa/mod_auth_digest.c
++++ apache2/modules/aaa/mod_auth_digest.c
+@@ -261,6 +261,26 @@ static void log_error_and_cleanup(char *
+ cleanup_tables(NULL);
+ }
+
++/* RMM helper functions that behave like single-step malloc/free. */
++
++static void *rmm_malloc(apr_rmm_t *rmm, apr_size_t size)
++{
++ apr_rmm_off_t offset = apr_rmm_malloc(rmm, size);
++
++ if (!offset) {
++ return NULL;
++ }
++
++ return apr_rmm_addr_get(rmm, offset);
++}
++
++static apr_status_t rmm_free(apr_rmm_t *rmm, void *alloc)
++{
++ apr_rmm_off_t offset = apr_rmm_offset_get(rmm, alloc);
++
++ return apr_rmm_free(rmm, offset);
++}
++
+ #if APR_HAS_SHARED_MEMORY
+
+ static int initialize_tables(server_rec *s, apr_pool_t *ctx)
+@@ -299,8 +319,8 @@ static int initialize_tables(server_rec
+ return !OK;
+ }
+
+- client_list = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*client_list) +
+- sizeof(client_entry*)*num_buckets));
++ client_list = rmm_malloc(client_rmm, sizeof(*client_list) +
++ sizeof(client_entry *) * num_buckets);
+ if (!client_list) {
+ log_error_and_cleanup("failed to allocate shared memory", -1, s);
+ return !OK;
+@@ -322,7 +342,7 @@ static int initialize_tables(server_rec
+
+ /* setup opaque */
+
+- opaque_cntr = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*opaque_cntr)));
++ opaque_cntr = rmm_malloc(client_rmm, sizeof(*opaque_cntr));
+ if (opaque_cntr == NULL) {
+ log_error_and_cleanup("failed to allocate shared memory", -1, s);
+ return !OK;
+@@ -339,7 +359,7 @@ static int initialize_tables(server_rec
+
+ /* setup one-time-nonce counter */
+
+- otn_counter = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(*otn_counter)));
++ otn_counter = rmm_malloc(client_rmm, sizeof(*otn_counter));
+ if (otn_counter == NULL) {
+ log_error_and_cleanup("failed to allocate shared memory", -1, s);
+ return !OK;
+@@ -779,7 +799,7 @@ static client_entry *get_client(unsigned
+ * last entry in each bucket and updates the counters. Returns the
+ * number of removed entries.
+ */
+-static long gc(void)
++static long gc(server_rec *s)
+ {
+ client_entry *entry, *prev;
+ unsigned long num_removed = 0, idx;
+@@ -789,6 +809,12 @@ static long gc(void)
+ for (idx = 0; idx < client_list->tbl_len; idx++) {
+ entry = client_list->table[idx];
+ prev = NULL;
++
++ if (!entry) {
++ /* This bucket is empty. */
++ continue;
++ }
++
+ while (entry->next) { /* find last entry */
+ prev = entry;
+ entry = entry->next;
+@@ -800,8 +826,16 @@ static long gc(void)
+ client_list->table[idx] = NULL;
+ }
+ if (entry) { /* remove entry */
+- apr_rmm_free(client_rmm, apr_rmm_offset_get(client_rmm, entry));
++ apr_status_t err;
++
++ err = rmm_free(client_rmm, entry);
+ num_removed++;
++
++ if (err) {
++ /* Nothing we can really do but log... */
++ ap_log_error(APLOG_MARK, APLOG_ERR, err, s, APLOGNO()
++ "Failed to free auth_digest client allocation");
++ }
+ }
+ }
+
+@@ -835,16 +869,16 @@ static client_entry *add_client(unsigned
+
+ /* try to allocate a new entry */
+
+- entry = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(client_entry)));
++ entry = rmm_malloc(client_rmm, sizeof(client_entry));
+ if (!entry) {
+- long num_removed = gc();
++ long num_removed = gc(s);
+ ap_log_error(APLOG_MARK, APLOG_INFO, 0, s, APLOGNO(01766)
+ "gc'd %ld client entries. Total new clients: "
+ "%ld; Total removed clients: %ld; Total renewed clients: "
+ "%ld", num_removed,
+ client_list->num_created - client_list->num_renewed,
+ client_list->num_removed, client_list->num_renewed);
+- entry = apr_rmm_addr_get(client_rmm, apr_rmm_malloc(client_rmm, sizeof(client_entry)));
++ entry = rmm_malloc(client_rmm, sizeof(client_entry));
+ if (!entry) {
+ ap_log_error(APLOG_MARK, APLOG_ERR, 0, s, APLOGNO(01767)
+ "unable to allocate new auth_digest client");
diff --git a/debian/patches/series b/debian/patches/series
index 58eacd9..592e402 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -21,3 +21,4 @@ split_logfile-strict.patch
CVE-2016-5387.patch
mod_socache_memcache_idle_timeout.patch
mod_proxy_fcgi_304_body.patch
+CVE-2016-2161-mod_auth_digest_segfault.diff
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-apache/apache2.git
More information about the Pkg-apache-commits
mailing list