[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