[Pkg-apache-commits] r1349 - in /trunk/apache2: changelog patches/00list patches/083_range_regressions.dpatch

sf at alioth.debian.org sf at alioth.debian.org
Sun Sep 4 19:33:03 UTC 2011


Author: sf
Date: Sun Sep  4 19:33:03 2011
New Revision: 1349

URL: http://svn.debian.org/wsvn/pkg-apache/?sc=1&rev=1349
Log:
Fix some regressions related to Range requests caused by the CVE-2011-3192
fix

Added:
    trunk/apache2/patches/083_range_regressions.dpatch   (with props)
Modified:
    trunk/apache2/changelog
    trunk/apache2/patches/00list

Modified: trunk/apache2/changelog
URL: http://svn.debian.org/wsvn/pkg-apache/trunk/apache2/changelog?rev=1349&op=diff
==============================================================================
--- trunk/apache2/changelog (original)
+++ trunk/apache2/changelog Sun Sep  4 19:33:03 2011
@@ -1,6 +1,8 @@
 apache2 (2.2.20-1) UNRELEASED; urgency=low
 
   * New upstream release.
+  * Fix some regressions related to Range requests caused by the CVE-2011-3192
+    fix. Closes: #639825
 
  -- Stefan Fritsch <sf at debian.org>  Sun, 04 Sep 2011 20:29:20 +0200
 

Modified: trunk/apache2/patches/00list
URL: http://svn.debian.org/wsvn/pkg-apache/trunk/apache2/patches/00list?rev=1349&op=diff
==============================================================================
--- trunk/apache2/patches/00list (original)
+++ trunk/apache2/patches/00list Sun Sep  4 19:33:03 2011
@@ -22,6 +22,7 @@
 077_CacheIgnoreURLSessionIdentifiers.dpatch
 079_polish_translation.dpatch
 082_ab_num_requests
+083_range_regressions.dpatch
 099_config_guess_sub_update
 200_cp_suexec.dpatch
 201_build_suexec-custom.dpatch

Added: trunk/apache2/patches/083_range_regressions.dpatch
URL: http://svn.debian.org/wsvn/pkg-apache/trunk/apache2/patches/083_range_regressions.dpatch?rev=1349&op=file
==============================================================================
--- trunk/apache2/patches/083_range_regressions.dpatch (added)
+++ trunk/apache2/patches/083_range_regressions.dpatch Sun Sep  4 19:33:03 2011
@@ -1,0 +1,257 @@
+#! /bin/sh /usr/share/dpatch/dpatch-run
+## 083_range_regressions.dpatch by Stefan Fritsch <sf at debian.org>
+##
+## All lines beginning with `## DP:' are a description of the patch.
+## DP: Merge bug fixes from upstream trunk up to r1165062
+
+ at DPATCH@
+diff -urNad '--exclude=CVS' '--exclude=.svn' '--exclude=.git' '--exclude=.arch' '--exclude=.hg' '--exclude=_darcs' '--exclude=.bzr' trunk~/modules/http/byterange_filter.c trunk/modules/http/byterange_filter.c
+--- trunk~/modules/http/byterange_filter.c	2011-08-29 17:59:39.000000000 +0200
++++ trunk/modules/http/byterange_filter.c	2011-09-04 21:23:45.907107634 +0200
+@@ -83,8 +83,6 @@
+     apr_bucket *first = NULL, *last = NULL, *out_first = NULL, *e;
+     apr_uint64_t pos = 0, off_first = 0, off_last = 0;
+     apr_status_t rv;
+-    const char *s;
+-    apr_size_t len;
+     apr_uint64_t start64, end64;
+     apr_off_t pofft = 0;
+ 
+@@ -136,43 +134,9 @@
+         if (e == first) {
+             if (off_first != start64) {
+                 rv = apr_bucket_split(copy, (apr_size_t)(start64 - off_first));
+-                if (rv == APR_ENOTIMPL) {
+-                    rv = apr_bucket_read(copy, &s, &len, APR_BLOCK_READ);
+-                    if (rv != APR_SUCCESS) {
+-                        apr_brigade_cleanup(bbout);
+-                        return rv;
+-                    }
+-                    /*
+-                     * The read above might have morphed copy in a bucket
+-                     * of shorter length. So read and delete until we reached
+-                     * the correct bucket for splitting.
+-                     */
+-                    while (start64 - off_first > (apr_uint64_t)copy->length) {
+-                        apr_bucket *tmp = APR_BUCKET_NEXT(copy);
+-                        off_first += (apr_uint64_t)copy->length;
+-                        APR_BUCKET_REMOVE(copy);
+-                        apr_bucket_destroy(copy);
+-                        copy = tmp;
+-                        rv = apr_bucket_read(copy, &s, &len, APR_BLOCK_READ);
+-                        if (rv != APR_SUCCESS) {
+-                            apr_brigade_cleanup(bbout);
+-                            return rv;
+-                        }
+-                    }
+-                    if (start64 > off_first) {
+-                        rv = apr_bucket_split(copy, (apr_size_t)(start64 - off_first));
+-                        if (rv != APR_SUCCESS) {
+-                            apr_brigade_cleanup(bbout);
+-                            return rv;
+-                        }
+-                    }
+-                    else {
+-                        copy = APR_BUCKET_PREV(copy);
+-                    }
+-                }
+-                else if (rv != APR_SUCCESS) {
+-                        apr_brigade_cleanup(bbout);
+-                        return rv;
++                if (rv != APR_SUCCESS) {
++                    apr_brigade_cleanup(bbout);
++                    return rv;
+                 }
+                 out_first = APR_BUCKET_NEXT(copy);
+                 APR_BUCKET_REMOVE(copy);
+@@ -189,37 +153,9 @@
+             }
+             if (end64 - off_last != (apr_uint64_t)e->length) {
+                 rv = apr_bucket_split(copy, (apr_size_t)(end64 + 1 - off_last));
+-                if (rv == APR_ENOTIMPL) {
+-                    rv = apr_bucket_read(copy, &s, &len, APR_BLOCK_READ);
+-                    if (rv != APR_SUCCESS) {
+-                        apr_brigade_cleanup(bbout);
+-                        return rv;
+-                    }
+-                    /*
+-                     * The read above might have morphed copy in a bucket
+-                     * of shorter length. So read until we reached
+-                     * the correct bucket for splitting.
+-                     */
+-                    while (end64 + 1 - off_last > (apr_uint64_t)copy->length) {
+-                        off_last += (apr_uint64_t)copy->length;
+-                        copy = APR_BUCKET_NEXT(copy);
+-                        rv = apr_bucket_read(copy, &s, &len, APR_BLOCK_READ);
+-                        if (rv != APR_SUCCESS) {
+-                            apr_brigade_cleanup(bbout);
+-                            return rv;
+-                        }
+-                    }
+-                    if (end64 < off_last + (apr_uint64_t)copy->length - 1) {
+-                        rv = apr_bucket_split(copy, end64 + 1 - off_last);
+-                        if (rv != APR_SUCCESS) {
+-                            apr_brigade_cleanup(bbout);
+-                            return rv;
+-                        }
+-                    }
+-                }
+-                else if (rv != APR_SUCCESS) {
+-                        apr_brigade_cleanup(bbout);
+-                        return rv;
++                if (rv != APR_SUCCESS) {
++                    apr_brigade_cleanup(bbout);
++                    return rv;
+                 }
+                 copy = APR_BUCKET_NEXT(copy);
+                 if (copy != APR_BRIGADE_SENTINEL(bbout)) {
+@@ -243,6 +179,20 @@
+     apr_off_t end;
+ } indexes_t;
+ 
++static apr_status_t send_416(ap_filter_t *f, apr_bucket_brigade *tmpbb)
++{
++    apr_bucket *e;
++    conn_rec *c = f->r->connection;
++    ap_remove_output_filter(f);
++    f->r->status = HTTP_OK;
++    e = ap_bucket_error_create(HTTP_RANGE_NOT_SATISFIABLE, NULL,
++                               f->r->pool, c->bucket_alloc);
++    APR_BRIGADE_INSERT_TAIL(tmpbb, e);
++    e = apr_bucket_eos_create(c->bucket_alloc);
++    APR_BRIGADE_INSERT_TAIL(tmpbb, e);
++    return ap_pass_brigade(f->next, tmpbb);
++}
++
+ AP_CORE_DECLARE_NONSTD(apr_status_t) ap_byterange_filter(ap_filter_t *f,
+                                                          apr_bucket_brigade *bb)
+ {
+@@ -296,6 +246,12 @@
+         return ap_pass_brigade(f->next, bb);
+     }
+ 
++    /* this brigade holds what we will be sending */
++    bsend = apr_brigade_create(r->pool, c->bucket_alloc);
++
++    if (num_ranges < 0)
++        return send_416(f, bsend);
++
+     if (num_ranges > 1) {
+         /* Is ap_make_content_type required here? */
+         const char *orig_ct = ap_make_content_type(r, r->content_type);
+@@ -325,8 +281,6 @@
+         ap_xlate_proto_to_ascii(bound_head, strlen(bound_head));
+     }
+ 
+-    /* this brigade holds what we will be sending */
+-    bsend = apr_brigade_create(r->pool, c->bucket_alloc);
+     tmpbb = apr_brigade_create(r->pool, c->bucket_alloc);
+ 
+     idx = (indexes_t *)indexes->elts;
+@@ -384,15 +338,8 @@
+     }
+ 
+     if (found == 0) {
+-        ap_remove_output_filter(f);
+-        r->status = HTTP_OK;
+         /* bsend is assumed to be empty if we get here. */
+-        e = ap_bucket_error_create(HTTP_RANGE_NOT_SATISFIABLE, NULL,
+-                                   r->pool, c->bucket_alloc);
+-        APR_BRIGADE_INSERT_TAIL(bsend, e);
+-        e = apr_bucket_eos_create(c->bucket_alloc);
+-        APR_BRIGADE_INSERT_TAIL(bsend, e);
+-        return ap_pass_brigade(f->next, bsend);
++        return send_416(f, bsend);
+     }
+ 
+     if (num_ranges > 1) {
+@@ -424,7 +371,7 @@
+     const char *match;
+     const char *ct;
+     char *cur;
+-    int num_ranges = 0;
++    int num_ranges = 0, unsatisfiable = 0;
+     apr_off_t sum_lengths = 0;
+     indexes_t *idx;
+     int ranges = 1;
+@@ -497,14 +444,25 @@
+         char *errp;
+         apr_off_t number, start, end;
+ 
+-        if (!(dash = strchr(cur, '-'))) {
++        if (!*cur)
+             break;
++
++        /*
++         * Per RFC 2616 14.35.1: If there is at least one syntactically invalid
++         * byte-range-spec, we must ignore the whole header.
++         */
++
++        if (!(dash = strchr(cur, '-'))) {
++            return 0;
+         }
+ 
+-        if (dash == range) {
++        if (dash == cur) {
+             /* In the form "-5" */
+             if (apr_strtoff(&number, dash+1, &errp, 10) || *errp) {
+-                break;
++                return 0;
++            }
++            if (number < 1) {
++                return 0;
+             }
+             start = clength - number;
+             end = clength - 1;
+@@ -512,14 +470,17 @@
+         else {
+             *dash++ = '\0';
+             if (apr_strtoff(&number, cur, &errp, 10) || *errp) {
+-                break;
++                return 0;
+             }
+             start = number;
+             if (*dash) {
+                 if (apr_strtoff(&number, dash, &errp, 10) || *errp) {
+-                    break;
++                    return 0;
+                 }
+                 end = number;
++                if (start > end) {
++                    return 0;
++                }
+             }
+             else {                  /* "5-" */
+                 end = clength - 1;
+@@ -529,15 +490,14 @@
+         if (start < 0) {
+             start = 0;
+         }
++        if (start >= clength) {
++            unsatisfiable = 1;
++            continue;
++        }
+         if (end >= clength) {
+             end = clength - 1;
+         }
+ 
+-        if (start > end) {
+-            /* ignore? count? */
+-            break;
+-        }
+-
+         idx = (indexes_t *)apr_array_push(*indexes);
+         idx->start = start;
+         idx->end = end;
+@@ -546,6 +506,11 @@
+         num_ranges++;
+     }
+ 
++    if (num_ranges == 0 && unsatisfiable) {
++        /* If all ranges are unsatisfiable, we should return 416 */
++        return -1;
++    }
++
+     if (sum_lengths >= clength) {
+         ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+                       "Sum of ranges not smaller than file, ignoring.");

Propchange: trunk/apache2/patches/083_range_regressions.dpatch
------------------------------------------------------------------------------
    svn:executable = *




More information about the Pkg-apache-commits mailing list