From: Jim Jagielski Date: Mon, 20 Jul 2009 10:54:01 +0000 (+0000) Subject: * mod_include: fix potential segfault in get_include_var X-Git-Tag: 2.2.12~10 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=cc1870b32064048467a18b97277b2a3fef700078;p=thirdparty%2Fapache%2Fhttpd.git * mod_include: fix potential segfault in get_include_var http://markmail.org/message/jlc7t5edsjujbe37 Trunk patch: http://svn.apache.org/viewvc?view=rev&revision=795445 http://svn.apache.org/viewvc?view=rev&revision=795446 http://svn.apache.org/viewvc?view=rev&revision=795642 2.2.x patch: http://people.apache.org/~niq/patches/mod_include_get_include_var.patch +1: niq, minfrin, jim git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@795758 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/STATUS b/STATUS index 2759715e43d..1ea2c319dd3 100644 --- a/STATUS +++ b/STATUS @@ -85,13 +85,6 @@ RELEASE SHOWSTOPPERS: PATCHES ACCEPTED TO BACKPORT FROM TRUNK: [ start all new proposals below, under PATCHES PROPOSED. ] - * mod_include: fix potential segfault in get_include_var - http://markmail.org/message/jlc7t5edsjujbe37 - Trunk patch: http://svn.apache.org/viewvc?view=rev&revision=795445 - http://svn.apache.org/viewvc?view=rev&revision=795446 - 2.2.x patch: http://people.apache.org/~niq/patches/mod_include_get_include_var.patch - +1: niq, minfrin, jim - PATCHES PROPOSED TO BACKPORT FROM TRUNK: [ New proposals should be added at the end of the list ] diff --git a/modules/filters/mod_include.c b/modules/filters/mod_include.c index a174529e191..6ec0fa8950c 100644 --- a/modules/filters/mod_include.c +++ b/modules/filters/mod_include.c @@ -158,6 +158,7 @@ typedef struct { const char *rexp; apr_size_t nsub; ap_regmatch_t match[AP_MAX_REG_MATCH]; + int have_match; } backref_t; typedef struct { @@ -648,25 +649,26 @@ static const char *get_include_var(const char *var, include_ctx_t *ctx) * The choice of returning NULL strings on not-found, * v.s. empty strings on an empty match is deliberate. */ - if (!re) { + if (!re || !re->have_match) { ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, "regex capture $%" APR_SIZE_T_FMT " refers to no regex in %s", idx, r->filename); return NULL; } + else if (re->nsub < idx || idx >= AP_MAX_REG_MATCH) { + ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, + "regex capture $%" APR_SIZE_T_FMT + " is out of range (last regex was: '%s') in %s", + idx, re->rexp, r->filename); + return NULL; + } + else if (re->match[idx].rm_so < 0 || re->match[idx].rm_eo < 0) { + /* I don't think this can happen if have_match is true. + * But let's not risk a regression by dropping this + */ + return NULL; + } else { - if (re->nsub < idx || idx >= AP_MAX_REG_MATCH) { - ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r, - "regex capture $%" APR_SIZE_T_FMT - " is out of range (last regex was: '%s') in %s", - idx, re->rexp, r->filename); - return NULL; - } - - if (re->match[idx].rm_so < 0 || re->match[idx].rm_eo < 0) { - return NULL; - } - val = apr_pstrmemdup(ctx->dpool, re->source + re->match[idx].rm_so, re->match[idx].rm_eo - re->match[idx].rm_so); } @@ -914,7 +916,6 @@ static APR_INLINE int re_check(include_ctx_t *ctx, const char *string, { ap_regex_t *compiled; backref_t *re = ctx->intern->re; - int rc; compiled = ap_pregcomp(ctx->dpool, rexp, AP_REG_EXTENDED); if (!compiled) { @@ -930,10 +931,11 @@ static APR_INLINE int re_check(include_ctx_t *ctx, const char *string, re->source = apr_pstrdup(ctx->pool, string); re->rexp = apr_pstrdup(ctx->pool, rexp); re->nsub = compiled->re_nsub; - rc = !ap_regexec(compiled, string, AP_MAX_REG_MATCH, re->match, 0); + re->have_match = !ap_regexec(compiled, string, AP_MAX_REG_MATCH, + re->match, 0); ap_pregfree(ctx->dpool, compiled); - return rc; + return re->have_match; } static int get_ptoken(include_ctx_t *ctx, const char **parse, token_t *token, token_t *previous)