You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by ni...@apache.org on 2011/05/13 14:03:59 UTC

svn commit: r1102687 - in /apr/apr/trunk: CHANGES buckets/apr_brigade.c

Author: niq
Date: Fri May 13 12:03:59 2011
New Revision: 1102687

URL: http://svn.apache.org/viewvc?rev=1102687&view=rev
Log:
apr_brigades: prevent infinite loop on a corrupt brigade
PR 51062

Modified:
    apr/apr/trunk/CHANGES
    apr/apr/trunk/buckets/apr_brigade.c

Modified: apr/apr/trunk/CHANGES
URL: http://svn.apache.org/viewvc/apr/apr/trunk/CHANGES?rev=1102687&r1=1102686&r2=1102687&view=diff
==============================================================================
--- apr/apr/trunk/CHANGES [utf-8] (original)
+++ apr/apr/trunk/CHANGES [utf-8] Fri May 13 12:03:59 2011
@@ -1,6 +1,10 @@
                                                      -*- coding: utf-8 -*-
 Changes for APR 2.0.0
 
+  *) apr_brigades: add a check to prevent infinite while loop in case
+     of a corrupted brigade.  Problem evidenced in PR 51062.  Analysis by
+     Krzysztof KostaƂkowicz <KKostalkowicz ivmx.pl>, patch [Nick Kew].
+
   *) apr_socket_connect() on Windows: Handle WSAEISCONN.  PR 48736.
      [<inoue ariel-networks.com>, Jeff Trawick]
 

Modified: apr/apr/trunk/buckets/apr_brigade.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/buckets/apr_brigade.c?rev=1102687&r1=1102686&r2=1102687&view=diff
==============================================================================
--- apr/apr/trunk/buckets/apr_brigade.c (original)
+++ apr/apr/trunk/buckets/apr_brigade.c Fri May 13 12:03:59 2011
@@ -38,11 +38,16 @@ APR_DECLARE(apr_status_t) apr_brigade_cl
 {
     apr_bucket_brigade *b = data;
     apr_bucket *e;
+    apr_bucket *prev = NULL;
 
     APR_BRIGADE_CHECK_CONSISTENCY(b);
 
     while (!APR_BRIGADE_EMPTY(b)) {
         e = APR_BRIGADE_FIRST(b);
+        if (e == prev) {         /* PR#51062: prevent infinite loop on a corrupt brigade */
+            return APR_EGENERAL; /* FIXME: this should definitely be a "can't happen"!   */
+        }
+        prev = e;
         apr_bucket_delete(e);
     }
     /* We don't need to free(bb) because it's allocated from a pool. */
@@ -323,6 +328,7 @@ APR_DECLARE(apr_status_t) apr_brigade_sp
                                                  apr_off_t maxbytes)
 {
     apr_off_t readbytes = 0;
+    apr_bucket *prev = NULL;
 
     while (!APR_BRIGADE_EMPTY(bbIn)) {
         const char *pos;
@@ -332,6 +338,10 @@ APR_DECLARE(apr_status_t) apr_brigade_sp
         apr_bucket *e;
 
         e = APR_BRIGADE_FIRST(bbIn);
+        if (e == prev) {         /* PR#51062: prevent infinite loop on a corrupt brigade */
+            return APR_EGENERAL; /* FIXME: this should definitely be a "can't happen"!   */
+        }
+        prev = e;
         rv = apr_bucket_read(e, &str, &len, block);
 
         if (rv != APR_SUCCESS) {