httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Lars Eilebrecht <l...@eilebrecht.net>
Subject regex-related segfault in mod_include
Date Thu, 26 Feb 2009 18:58:56 GMT
Hi,

the following SSI statements triggers a segfault when QUERY_STRING
is empty (tested with 2.2.11):

  <!--#if expr="$QUERY_STRING = /foobar=([0-9]+)$/" -->
    <!--#set var="foobar" value="$1" -->
   <!--#else -->
    <!--#set var="foobar" value="$1" -->	
  <!--#endif -->

I tracked this down to get_include_var() in mod_include.c:

--snip--
static const char *get_include_var(const char *var, include_ctx_t *ctx)
{
    const char *val;
    request_rec *r = ctx->intern->r;

    if (apr_isdigit(*var) && !var[1]) {
        apr_size_t idx = *var - '0';
        backref_t *re = ctx->intern->re;

        /* Handle $0 .. $9 from the last regex evaluated.
         * The choice of returning NULL strings on not-found,
         * v.s. empty strings on an empty match is deliberate.
         */
        if (!re) {
            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;
            }

            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);
        }
    }
    else {
        val = apr_table_get(r->subprocess_env, var);

        if (val == LAZY_VALUE) {
            val = add_include_vars_lazy(r, var);
        }
    }

    return val;
}
--snip--

The segfault happens with apr_pstrmemdup(), because 
"re->source + re->match[idx].rm_so" ends up being out of bounds.

So despite the regex not matching, "ctx->intern->re" is actually
not NULL, but I can't seem to figure out why this is the case.

Anyone any idea?

ciao...
-- 
Lars Eilebrecht
lars@eilebrecht.net


Mime
View raw message