]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Fold in the CAN-2003-0542 regex patch.
authorSander Striker <striker@apache.org>
Fri, 24 Oct 2003 16:19:32 +0000 (16:19 +0000)
committerSander Striker <striker@apache.org>
Fri, 24 Oct 2003 16:19:32 +0000 (16:19 +0000)
git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/APACHE_2_0_BRANCH@101555 13f79535-47bb-0310-9956-ffa450edef68

CHANGES
include/httpd.h
modules/mappers/mod_alias.c
modules/mappers/mod_rewrite.c
modules/mappers/mod_rewrite.h
modules/proxy/proxy_ftp.c

diff --git a/CHANGES b/CHANGES
index a3517fa2e7da9fd9b90dca7a13cd70fe4a64bcff..03d30ee66198409c511bf5a0ce0c9bc080150dbd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,10 @@
 Changes with Apache 2.0.48
 
+  *) SECURITY: CAN-2003-0542 (cve.mitre.org)
+     Fix buffer overflows in mod_alias and mod_rewrite which occurred if
+     one configured a regular expression with more than 9 captures.
+     [AndrĂ© Malo]
+
   *) mod_include: fix segfault which occured if the filename was not
      set, for example, when processing some error conditions.
      PR 23836.  [Brian Akins <bakins@web.turner.com>, AndrĂ© Malo]
index 7951a8c087441cc765ab30016dbf0db30ded5e7e..860a131f3f1b5d860993d3f1cbddc4b724987da6 100644 (file)
@@ -321,6 +321,9 @@ extern "C" {
 /** The size of the server's internal read-write buffers */
 #define AP_IOBUFSIZE 8192
 
+/** The max number of regex captures that can be expanded by ap_pregsub */
+#define AP_MAX_REG_MATCH 10
+
 /**
  * APR_HAS_LARGE_FILES introduces the problem of spliting sendfile into 
  * mutiple buckets, no greater than MAX(apr_size_t), and more granular 
index b5bea281c05070461c9f019c29aa94ae25aac0b4..60bf7c79623b1eaf4faa48b9d2218aa55fa42259 100644 (file)
@@ -328,7 +328,7 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
                             int doesc, int *status)
 {
     alias_entry *entries = (alias_entry *) aliases->elts;
-    regmatch_t regm[10];
+    regmatch_t regm[AP_MAX_REG_MATCH];
     char *found = NULL;
     int i;
 
@@ -337,11 +337,10 @@ static char *try_alias_list(request_rec *r, apr_array_header_t *aliases,
         int l;
 
         if (p->regexp) {
-            if (!ap_regexec(p->regexp, r->uri, p->regexp->re_nsub + 1, regm,
-                            0)) {
+            if (!ap_regexec(p->regexp, r->uri, AP_MAX_REG_MATCH, regm, 0)) {
                 if (p->real) {
                     found = ap_pregsub(r->pool, p->real, r->uri,
-                                    p->regexp->re_nsub + 1, regm);
+                                       AP_MAX_REG_MATCH, regm);
                     if (found && doesc) {
                         apr_uri_t uri;
                         apr_uri_parse(r->pool, found, &uri);
index 63d17632b6e97c433c0e1564959a6206f3c12e29..ed1d2e4c8397fd541ac4b3d7c1e4f599e6c4e6d3 100644 (file)
@@ -1940,7 +1940,7 @@ static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p,
     const char *vary;
     char newuri[MAX_STRING_LEN];
     regex_t *regexp;
-    regmatch_t regmatch[MAX_NMATCH];
+    regmatch_t regmatch[AP_MAX_REG_MATCH];
     backrefinfo *briRR = NULL;
     backrefinfo *briRC = NULL;
     int prefixstrip;
@@ -1997,7 +1997,7 @@ static int apply_rewrite_rule(request_rec *r, rewriterule_entry *p,
         rewritelog(r, 3, "[per-dir %s] applying pattern '%s' to uri '%s'",
                    perdir, p->pattern, uri);
     }
-    rc = (ap_regexec(regexp, uri, regexp->re_nsub+1, regmatch, 0) == 0);
+    rc = (ap_regexec(regexp, uri, AP_MAX_REG_MATCH, regmatch, 0) == 0);
     if (! (( rc && !(p->flags & RULEFLAG_NOTMATCH)) ||
            (!rc &&  (p->flags & RULEFLAG_NOTMATCH))   ) ) {
         return 0;
@@ -2293,7 +2293,7 @@ static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p,
     char input[MAX_STRING_LEN];
     apr_finfo_t sb;
     request_rec *rsub;
-    regmatch_t regmatch[MAX_NMATCH];
+    regmatch_t regmatch[AP_MAX_REG_MATCH];
     int rc;
 
     /*
@@ -2398,8 +2398,7 @@ static int apply_rewrite_cond(request_rec *r, rewritecond_entry *p,
     }
     else {
         /* it is really a regexp pattern, so apply it */
-        rc = (ap_regexec(p->regexp, input,
-                         p->regexp->re_nsub+1, regmatch,0) == 0);
+        rc = (ap_regexec(p->regexp, input, AP_MAX_REG_MATCH, regmatch,0) == 0);
 
         /* if it isn't a negated pattern and really matched
            we update the passed-through regex subst info structure */
@@ -2558,7 +2557,7 @@ static void do_expand(request_rec *r, char *input, char *buffer, int nbuf,
                 bri = briRC;
             }
             /* see ap_pregsub() in src/main/util.c */
-            if (bri && n <= bri->nsub
+            if (bri && n < AP_MAX_REG_MATCH
                 && bri->regmatch[n].rm_eo > bri->regmatch[n].rm_so) {
                 span = bri->regmatch[n].rm_eo - bri->regmatch[n].rm_so;
                 if (span > space) {
index b45c5f03b222752c19bb915ed2d3de72f90a9848..bbb5bc8cc87b9b5c86432f314be98579f3953f4e 100644 (file)
 /*** max cookie size in rfc 2109 ***/
 #define MAX_COOKIE_LEN 4096
 
-#define MAX_NMATCH    10
-
 /* default maximum number of internal redirects */
 #define REWRITE_REDIRECT_LIMIT 10
 
@@ -333,7 +331,7 @@ typedef struct cache {
 typedef struct backrefinfo {
     char *source;
     int nsub;
-    regmatch_t regmatch[10];
+    regmatch_t regmatch[AP_MAX_REG_MATCH];
 } backrefinfo;
 
 
index c38773cb6b6f6dae9a4265351c6996404e6fe116..c6c1f65e25a068eee873b59d302af9a1e98571dc 100644 (file)
@@ -319,6 +319,10 @@ typedef struct {
     }    state;
 }      proxy_dir_ctx_t;
 
+/* fallback regex for ls -s1;  ($0..$2) == 3 */
+#define LS_REG_PATTERN "^ *([0-9]+) +([^ ]+)$"
+#define LS_REG_MATCH   3
+
 apr_status_t ap_proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *in)
 {
     request_rec *r = f->r;
@@ -462,10 +466,10 @@ apr_status_t ap_proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *in)
         int eos = 0;
 
         regex_t *re = NULL;
-        regmatch_t re_result[3];
+        regmatch_t re_result[LS_REG_MATCH];
 
         /* Compile the output format of "ls -s1" as a fallback for non-unix ftp listings */
-        re = ap_pregcomp(p, "^ *([0-9]+) +([^ ]+)$", REG_EXTENDED);
+        re = ap_pregcomp(p, LS_REG_PATTERN, REG_EXTENDED);
 
         /* get a complete line */
         /* if the buffer overruns - throw data away */
@@ -581,7 +585,7 @@ apr_status_t ap_proxy_send_dir_filter(ap_filter_t *f, apr_bucket_brigade *in)
             }
         }
         /* Try a fallback for listings in the format of "ls -s1" */
-        else if (0 == ap_regexec(re, ctx->buffer, 3, re_result, 0)) {
+        else if (0 == ap_regexec(re, ctx->buffer, LS_REG_MATCH, re_result, 0)) {
 
             filename = apr_pstrndup(p, &ctx->buffer[re_result[2].rm_so], re_result[2].rm_eo - re_result[2].rm_so);