From: Eric Covener Date: Fri, 5 Jun 2026 10:17:58 +0000 (+0000) Subject: ap_regname: restrict to reasonable captures X-Git-Url: http://git.ipfire.org/index.cgi?a=commitdiff_plain;h=52cb79b19e110bdd42bffc696844f801fb3c4a2d;p=thirdparty%2Fapache%2Fhttpd.git ap_regname: restrict to reasonable captures git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1935014 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/include/ap_regex.h b/include/ap_regex.h index a986194151..6ed47a5195 100644 --- a/include/ap_regex.h +++ b/include/ap_regex.h @@ -228,6 +228,8 @@ AP_DECLARE(apr_size_t) ap_regerror(int errcode, const ap_regex_t *preg, * @param prefix An optional prefix to add to the returned names. AP_REG_MATCH * is the recommended prefix. * @param upper If non zero, uppercase the names + * @return number of regex backrefernces returned, -1 for error + * for successful match, AP_REG_NOMATCH otherwise */ AP_DECLARE(int) ap_regname(const ap_regex_t *preg, apr_array_header_t *names, const char *prefix, diff --git a/modules/proxy/mod_proxy.c b/modules/proxy/mod_proxy.c index 46d3b07145..3c2a28d925 100644 --- a/modules/proxy/mod_proxy.c +++ b/modules/proxy/mod_proxy.c @@ -2945,7 +2945,9 @@ static const char *proxysection(cmd_parms *cmd, void *mconfig, const char *arg) if (r) { conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *)); - ap_regname(r, conf->refs, AP_REG_MATCH, 1); + if (ap_regname(r, conf->refs, AP_REG_MATCH, 1) < 0) { + return "Error processing regex captures"; + } } ap_add_per_proxy_conf(cmd->server, new_dir_conf); diff --git a/server/core.c b/server/core.c index 1dad12348c..315d6b5bac 100644 --- a/server/core.c +++ b/server/core.c @@ -2600,7 +2600,9 @@ static const char *dirsection(cmd_parms *cmd, void *mconfig, const char *arg) if (cmd->regex) { conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *)); - ap_regname(cmd->regex, conf->refs, AP_REG_MATCH, 1); + if (ap_regname(cmd->regex, conf->refs, AP_REG_MATCH, 1) < 0) { + return "Error processing regex captures"; + } } /* Make this explicit - the "/" root has 0 elements, that is, we @@ -2685,7 +2687,9 @@ static const char *urlsection(cmd_parms *cmd, void *mconfig, const char *arg) if (cmd->regex) { conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *)); - ap_regname(cmd->regex, conf->refs, AP_REG_MATCH, 1); + if (ap_regname(cmd->regex, conf->refs, AP_REG_MATCH, 1) < 0) { + return "Error processing regex captures"; + } } ap_add_per_url_conf(cmd->server, new_url_conf); @@ -2776,7 +2780,9 @@ static const char *filesection(cmd_parms *cmd, void *mconfig, const char *arg) if (cmd->regex) { conf->refs = apr_array_make(cmd->pool, 8, sizeof(char *)); - ap_regname(cmd->regex, conf->refs, AP_REG_MATCH, 1); + if (ap_regname(cmd->regex, conf->refs, AP_REG_MATCH, 1) < 0) { + return "Error processing regex captures"; + } } ap_add_file_conf(cmd->pool, (core_dir_config *)mconfig, new_file_conf); diff --git a/server/util_pcre.c b/server/util_pcre.c index f8817d2896..3c1dc8b2ff 100644 --- a/server/util_pcre.c +++ b/server/util_pcre.c @@ -590,7 +590,16 @@ AP_DECLARE(int) ap_regname(const ap_regex_t *preg, for (i = 0; i < namecount; i++) { const char *offset = nametable + i * nameentrysize; - int capture = ((offset[0] << 8) + offset[1]); + int capture = (((unsigned char)offset[0] << 8) + (unsigned char)offset[1]); + + /* Sanity check: reject unreasonably large capture group numbers. + * PCRE allows up to 65535 groups, but such large numbers would + * cause excessive memory allocation. Limit to a reasonable maximum. + */ + if (capture > 1024) { + return -1; + } + while (names->nelts <= capture) { apr_array_push(names); }