From: Eric Covener Date: Wed, 14 Jan 2015 13:20:49 +0000 (+0000) Subject: Merge r1648394 from trunk: X-Git-Tag: 2.4.11~17 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=44309cd8e225eb7865a0c612fc738c5c393f81f1;p=apache Merge r1648394 from trunk: Configuration files with long lines and continuation characters are not read properly. PR 55910. Submitted By: Manuel Mausz Committed By: covener git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.4.x@1651653 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/CHANGES b/CHANGES index 89807b499a..765eb376d0 100644 --- a/CHANGES +++ b/CHANGES @@ -5,6 +5,7 @@ Changes with Apache 2.4.11 *) SECURITY: CVE-2014-3583 (cve.mitre.org) mod_proxy_fcgi: Fix a potential crash due to buffer over-read, with response headers' size above 8K. [Yann Ylavic, Jeff Trawick] + *) SECURITY: CVE-2014-3581 (cve.mitre.org) mod_cache: Avoid a crash when Content-Type has an empty value. PR 56924. [Mark Montague , Jan Kaluza] @@ -21,6 +22,9 @@ Changes with Apache 2.4.11 request headers earlier. Adds "MergeTrailers" directive to restore legacy behavior. [Edward Lu, Yann Ylavic, Joe Orton, Eric Covener] + *) core: Configuration files with long lines and continuation characters + are not read properly. PR 55910. [Manuel Mausz ] + *) mod_include: the 'env' function was incorrectly handled as 'getenv' if the leading 'e' was written in upper case in statements. [Christophe Jaillet] diff --git a/server/util.c b/server/util.c index cd2aa82d37..7c17b04a49 100644 --- a/server/util.c +++ b/server/util.c @@ -970,20 +970,20 @@ AP_DECLARE(const char *) ap_pcfg_strerror(apr_pool_t *p, ap_configfile_t *cfp, /* Read one line from open ap_configfile_t, strip LF, increase line number */ /* If custom handler does not define a getstr() function, read char by char */ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, - ap_configfile_t *cfp) + apr_size_t offset, ap_configfile_t *cfp) { apr_status_t rc; /* If a "get string" function is defined, use it */ if (cfp->getstr != NULL) { char *cp; - char *cbuf = buf; - apr_size_t cbufsize = bufsize; + char *cbuf = buf + offset; + apr_size_t cbufsize = bufsize - offset; while (1) { ++cfp->line_number; rc = cfp->getstr(cbuf, cbufsize, cfp->param); if (rc == APR_EOF) { - if (cbuf != buf) { + if (cbuf != buf + offset) { *cbuf = '\0'; break; } @@ -1001,11 +1001,11 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, */ cp = cbuf; cp += strlen(cp); - if (cp > cbuf && cp[-1] == LF) { + if (cp > buf && cp[-1] == LF) { cp--; - if (cp > cbuf && cp[-1] == CR) + if (cp > buf && cp[-1] == CR) cp--; - if (cp > cbuf && cp[-1] == '\\') { + if (cp > buf && cp[-1] == '\\') { cp--; /* * line continuation requested - @@ -1023,19 +1023,19 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, } } else { /* No "get string" function defined; read character by character */ - apr_size_t i = 0; + apr_size_t i = offset; if (bufsize < 2) { /* too small, assume caller is crazy */ return APR_EINVAL; } - buf[0] = '\0'; + buf[offset] = '\0'; while (1) { char c; rc = cfp->getch(&c, cfp->param); if (rc == APR_EOF) { - if (i > 0) + if (i > offset) break; else return APR_EOF; @@ -1053,11 +1053,11 @@ static apr_status_t ap_cfg_getline_core(char *buf, apr_size_t bufsize, break; } } - else if (i >= bufsize - 2) { - return APR_ENOSPC; - } buf[i] = c; ++i; + if (i >= bufsize - 1) { + return APR_ENOSPC; + } } buf[i] = '\0'; } @@ -1091,7 +1091,7 @@ static int cfg_trim_line(char *buf) AP_DECLARE(apr_status_t) ap_cfg_getline(char *buf, apr_size_t bufsize, ap_configfile_t *cfp) { - apr_status_t rc = ap_cfg_getline_core(buf, bufsize, cfp); + apr_status_t rc = ap_cfg_getline_core(buf, bufsize, 0, cfp); if (rc == APR_SUCCESS) cfg_trim_line(buf); return rc; @@ -1118,7 +1118,7 @@ AP_DECLARE(apr_status_t) ap_varbuf_cfg_getline(struct ap_varbuf *vb, } for (;;) { - rc = ap_cfg_getline_core(vb->buf + vb->strlen, vb->avail - vb->strlen, cfp); + rc = ap_cfg_getline_core(vb->buf, vb->avail, vb->strlen, cfp); if (rc == APR_ENOSPC || rc == APR_SUCCESS) vb->strlen += strlen(vb->buf + vb->strlen); if (rc != APR_ENOSPC)