Version in base suite: 2.2.9-10+lenny4 Version in overlay suite: (not present) Base version: apache2_2.2.9-10+lenny4 Target version: apache2_2.2.9-10+lenny5 Base file: /org/ftp.debian.org/ftp/pool/main/a/apache2/apache2_2.2.9-10+lenny4.dsc Target file: /org/ftp.debian.org/queue/p-u-new/apache2_2.2.9-10+lenny5.dsc apache2-2.2.9/debian/apache2.2-common.postinst | 1 apache2-2.2.9/debian/apache2.2-common.postrm | 1 apache2-2.2.9/debian/changelog | 20 +++ apache2-2.2.9/debian/control | 4 apache2-2.2.9/debian/patches/00list | 4 apache2-2.2.9/debian/patches/071_CVE-2009-1891.dpatch | 25 +++ debian/patches/068_fix_deflate_etag_PR45023.dpatch | 51 +++++++ debian/patches/069_fix_mod_rewrite_B_PR45529.dpatch | 85 +++++++++++++ debian/patches/074_CVE-2009-3094.dpatch | 116 ++++++++++++++++++ debian/patches/075_CVE-2009-3095.dpatch | 33 +++++ 10 files changed, 338 insertions(+), 2 deletions(-) diff -u apache2-2.2.9/debian/apache2.2-common.postinst apache2-2.2.9/debian/apache2.2-common.postinst --- apache2-2.2.9/debian/apache2.2-common.postinst +++ apache2-2.2.9/debian/apache2.2-common.postinst @@ -101,6 +101,7 @@ ! -e /var/www/index.pl -a \ ! -e /var/www/index.php -a \ ! -e /var/www/index.xhtml -a \ + ! -e /var/www/index.shtml -a \ ! -e /var/www/index.htm ] ; then cp /usr/share/apache2/default-site/index.html /var/www/index.html fi diff -u apache2-2.2.9/debian/control apache2-2.2.9/debian/control --- apache2-2.2.9/debian/control +++ apache2-2.2.9/debian/control @@ -96,7 +96,7 @@ Architecture: any Depends: ${shlibs:Depends}, apache2.2-common Conflicts: apache2-suexec, apache-common -Replaces: apache2-suexec +Replaces: apache2-suexec, apache2.2-common ( << 2.2.8-5~ ) Description: Standard suexec program for Apache 2 mod_suexec Provides the standard suexec helper program for mod_suexec. This version is compiled with document root /var/www and userdir suffix public_html. If you @@ -109,7 +109,7 @@ Depends: ${shlibs:Depends}, apache2.2-common Provides: apache2-suexec Conflicts: apache2-suexec, apache-common -Replaces: apache2-suexec +Replaces: apache2-suexec, apache2.2-common ( << 2.2.8-5~ ) Description: Configurable suexec program for Apache 2 mod_suexec Provides a customizable version of the suexec helper program for mod_suexec. This is not the version from upstream, but can be configured with a diff -u apache2-2.2.9/debian/apache2.2-common.postrm apache2-2.2.9/debian/apache2.2-common.postrm --- apache2-2.2.9/debian/apache2.2-common.postrm +++ apache2-2.2.9/debian/apache2.2-common.postrm @@ -6,6 +6,7 @@ rm -f /etc/apache2/httpd.conf \ /etc/apache2/ports.conf.dpkg-apache2.2-common.existed \ /var/cache/apache2/reload \ + /var/log/apache2/other_vhosts_access.log* \ /var/log/apache2/access.log* \ /var/log/apache2/error.log* diff -u apache2-2.2.9/debian/changelog apache2-2.2.9/debian/changelog --- apache2-2.2.9/debian/changelog +++ apache2-2.2.9/debian/changelog @@ -1,3 +1,23 @@ +apache2 (2.2.9-10+lenny5) stable; urgency=low + + * Minor security fixes in mod_proxy_ftp (closes: #545951): + - DoS by malicious ftp server (CVE-2009-3094) + - missing input sanitization: a user could execute arbitrary ftp commands + on the backend ftp server (CVE-2009-3095) + * Fix segfault in legacy ap_r* API which is triggered more often since + the fix for CVE-2009-1891 was applied (closes: #537665). + * Take care to not override existing index.shtml files when upgrading from + before 2.2.8-1 (closes: #517089). + * mod_deflate: Fix invalid etag to be emitted for on-the-fly gzip + content-encoding. This prevented apache from sending "304 NOT MODIFIED" + responses for compressed content. + * mod_rewrite: Fix "B" flag breakage (closes: #524268) + * Properly declare that apache2-suexec* replace files in old versions of + apache2.2-common (closes: #528951). + * Remove other_vhosts_access.log on package purge. + + -- Stefan Fritsch Mon, 05 Oct 2009 19:07:08 +0200 + apache2 (2.2.9-10+lenny4) stable-security; urgency=high * Security fixes: diff -u apache2-2.2.9/debian/patches/00list apache2-2.2.9/debian/patches/00list --- apache2-2.2.9/debian/patches/00list +++ apache2-2.2.9/debian/patches/00list @@ -26,10 +26,14 @@ 065_mod_proxy_segfault_PR45792.dpatch 066_mpm_worker_segfault_PR45605.dpatch 067_check_pollset_create_error.dpatch +068_fix_deflate_etag_PR45023.dpatch +069_fix_mod_rewrite_B_PR45529.dpatch 070_CVE-2009-1195_mod_include_noexec.dpatch 071_CVE-2009-1891.dpatch 072_CVE-2009-1890.dpatch 073_no_deflate_for_HEAD.dpatch +074_CVE-2009-3094.dpatch +075_CVE-2009-3095.dpatch 099_config_guess_sub_update 200_cp_suexec.dpatch 201_build_suexec-custom.dpatch diff -u apache2-2.2.9/debian/patches/071_CVE-2009-1891.dpatch apache2-2.2.9/debian/patches/071_CVE-2009-1891.dpatch --- apache2-2.2.9/debian/patches/071_CVE-2009-1891.dpatch +++ apache2-2.2.9/debian/patches/071_CVE-2009-1891.dpatch @@ -3,6 +3,7 @@ ## All lines beginning with `## DP:' are a description of the patch. ## DP: mod_deflate DoS ## DP: http://mail-archives.apache.org/mod_mbox/httpd-dev/200907.mbox/<20090703100048.GA4492@redhat.com> +## DP: also fix segfault which is triggered more often with this patch (#537665, upstream svn r800333) @DPATCH@ --- a/server/core_filters.c (revision 790833) @@ -36,0 +38,24 @@ +diff --git a/server/util_filter.c b/server/util_filter.c +index 7d48b52..b2e7b58 100644 +--- a/server/util_filter.c ++++ b/server/util_filter.c +@@ -578,8 +578,18 @@ AP_DECLARE_NONSTD(apr_status_t) ap_filter_flush(apr_bucket_brigade *bb, + void *ctx) + { + ap_filter_t *f = ctx; ++ apr_status_t rv; + +- return ap_pass_brigade(f, bb); ++ rv = ap_pass_brigade(f, bb); ++ ++ /* Before invocation of the flush callback, apr_brigade_write et ++ * al may place transient buckets in the brigade, which will fall ++ * out of scope after returning. Empty the brigade here, to avoid ++ * issues with leaving such buckets in the brigade if some filter ++ * fails and leaves a non-empty brigade. */ ++ apr_brigade_cleanup(bb); ++ ++ return rv; + } + + AP_DECLARE(apr_status_t) ap_fflush(ap_filter_t *f, apr_bucket_brigade *bb) only in patch2: unchanged: --- apache2-2.2.9.orig/debian/patches/074_CVE-2009-3094.dpatch +++ apache2-2.2.9/debian/patches/074_CVE-2009-3094.dpatch @@ -0,0 +1,116 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: CVE-2009-3094: mod_proxy_ftp NULL pointer dereference on error paths. + +@DPATCH@ +commit 239d6a38f8fba2a2e03ee632985706a0a77d60dd +Author: Graham Leggett +Date: Mon Sep 14 20:51:49 2009 +0000 + + Backport 814652, 814785 + CVE-2009-3094: mod_proxy_ftp NULL pointer dereference on error paths. + Submitted by: Stefan Fritsch , Joe Orton + + + git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@814844 13f79535-47bb-0310-9956-ffa450edef68 + +diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c +index 639f9f8..fdcfc6a 100644 +--- a/modules/proxy/mod_proxy_ftp.c ++++ b/modules/proxy/mod_proxy_ftp.c +@@ -604,6 +604,31 @@ static apr_status_t proxy_send_dir_filter(ap_filter_t *f, + return APR_SUCCESS; + } + ++/* Parse EPSV reply and return port, or zero on error. */ ++static apr_port_t parse_epsv_reply(const char *reply) ++{ ++ const char *p; ++ char *ep; ++ long port; ++ ++ /* Reply syntax per RFC 2428: "229 blah blah (|||port|)" where '|' ++ * can be any character in ASCII from 33-126, obscurely. Verify ++ * the syntax. */ ++ p = ap_strchr_c(reply, '('); ++ if (p == NULL || !p[1] || p[1] != p[2] || p[1] != p[3] ++ || p[4] == p[1]) { ++ return 0; ++ } ++ ++ errno = 0; ++ port = strtol(p + 4, &ep, 10); ++ if (errno || port < 1 || port > 65535 || ep[0] != p[1] || ep[1] != ')') { ++ return 0; ++ } ++ ++ return (apr_port_t)port; ++} ++ + /* + * Generic "send FTP command to server" routine, using the control socket. + * Returns the FTP returncode (3 digit code) +@@ -1210,26 +1235,11 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, + return ftp_proxyerror(r, backend, HTTP_BAD_GATEWAY, ftpmessage); + } + else if (rc == 229) { +- char *pstr; +- char *tok_cntx; ++ /* Parse the port out of the EPSV reply. */ ++ data_port = parse_epsv_reply(ftpmessage); + +- pstr = ftpmessage; +- pstr = apr_strtok(pstr, " ", &tok_cntx); /* separate result code */ +- if (pstr != NULL) { +- if (*(pstr + strlen(pstr) + 1) == '=') { +- pstr += strlen(pstr) + 2; +- } +- else { +- pstr = apr_strtok(NULL, "(", &tok_cntx); /* separate address & +- * port params */ +- if (pstr != NULL) +- pstr = apr_strtok(NULL, ")", &tok_cntx); +- } +- } +- +- if (pstr) { ++ if (data_port) { + apr_sockaddr_t *epsv_addr; +- data_port = atoi(pstr + 3); + + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: EPSV contacting remote host on port %d", +@@ -1272,10 +1282,6 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, + connect = 1; + } + } +- else { +- /* and try the regular way */ +- apr_socket_close(data_sock); +- } + } + } + +@@ -1364,10 +1370,6 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, + connect = 1; + } + } +- else { +- /* and try the regular way */ +- apr_socket_close(data_sock); +- } + } + } + /*bypass:*/ +@@ -1851,7 +1853,9 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, + * for a slow client to eat these bytes + */ + ap_flush_conn(data); +- apr_socket_close(data_sock); ++ if (data_sock) { ++ apr_socket_close(data_sock); ++ } + data_sock = NULL; + ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, + "proxy: FTP: data connection closed"); only in patch2: unchanged: --- apache2-2.2.9.orig/debian/patches/075_CVE-2009-3095.dpatch +++ apache2-2.2.9/debian/patches/075_CVE-2009-3095.dpatch @@ -0,0 +1,33 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: CVE-2009-3095: mod_proxy_ftp sanity check authn credentials. + +@DPATCH@ +commit 5e9bca418ec4087e398053dac44348b977b219e8 +Author: Graham Leggett +Date: Mon Sep 14 20:53:28 2009 +0000 + + Backport 814045 + CVE-2009-3095: mod_proxy_ftp sanity check authn credentials. + Submitted by: Stefan Fritsch , Joe Orton + + + git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/2.2.x@814847 13f79535-47bb-0310-9956-ffa450edef68 + +diff --git a/modules/proxy/mod_proxy_ftp.c b/modules/proxy/mod_proxy_ftp.c +index fdcfc6a..924ac31 100644 +--- a/modules/proxy/mod_proxy_ftp.c ++++ b/modules/proxy/mod_proxy_ftp.c +@@ -912,6 +912,11 @@ static int proxy_ftp_handler(request_rec *r, proxy_worker *worker, + if ((password = apr_table_get(r->headers_in, "Authorization")) != NULL + && strcasecmp(ap_getword(r->pool, &password, ' '), "Basic") == 0 + && (password = ap_pbase64decode(r->pool, password))[0] != ':') { ++ /* Check the decoded string for special characters. */ ++ if (!ftp_check_string(password)) { ++ return ap_proxyerror(r, HTTP_BAD_REQUEST, ++ "user credentials contained invalid character"); ++ } + /* + * Note that this allocation has to be made from r->connection->pool + * because it has the lifetime of the connection. The other only in patch2: unchanged: --- apache2-2.2.9.orig/debian/patches/068_fix_deflate_etag_PR45023.dpatch +++ apache2-2.2.9/debian/patches/068_fix_deflate_etag_PR45023.dpatch @@ -0,0 +1,51 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## 068_fix_deflate_etag_PR45023.dpatch by Stefan Fritsch +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: https://issues.apache.org/bugzilla/show_bug.cgi?id=45023 + +@DPATCH@ +diff -urNad lenny-apache2~/modules/filters/mod_deflate.c lenny-apache2/modules/filters/mod_deflate.c +--- lenny-apache2~/modules/filters/mod_deflate.c 2009-05-17 10:55:23.000000000 +0200 ++++ lenny-apache2/modules/filters/mod_deflate.c 2009-05-17 10:59:52.191084777 +0200 +@@ -372,23 +372,7 @@ + ctx->libz_end_func(&ctx->stream); + return APR_SUCCESS; + } +-/* PR 39727: we're screwing up our clients if we leave a strong ETag +- * header while transforming content. Henrik Nordstrom suggests +- * appending ";gzip". +- * +- * Pending a more thorough review of our Etag handling, let's just +- * implement his suggestion. It fixes the bug, or at least turns it +- * from a showstopper to an inefficiency. And it breaks nothing that +- * wasn't already broken. +- */ +-static void deflate_check_etag(request_rec *r, const char *transform) +-{ +- const char *etag = apr_table_get(r->headers_out, "ETag"); +- if (etag && (((etag[0] != 'W') && (etag[0] !='w')) || (etag[1] != '/'))) { +- apr_table_set(r->headers_out, "ETag", +- apr_pstrcat(r->pool, etag, "-", transform, NULL)); +- } +-} ++ + static apr_status_t deflate_out_filter(ap_filter_t *f, + apr_bucket_brigade *bb) + { +@@ -586,7 +570,6 @@ + } + apr_table_unset(r->headers_out, "Content-Length"); + apr_table_unset(r->headers_out, "Content-MD5"); +- deflate_check_etag(r, "gzip"); + + /* initialize deflate output buffer */ + ctx->stream.next_out = ctx->buffer; +@@ -1079,7 +1062,6 @@ + /* these are unlikely to be set anyway, but ... */ + apr_table_unset(r->headers_out, "Content-Length"); + apr_table_unset(r->headers_out, "Content-MD5"); +- deflate_check_etag(r, "gunzip"); + + /* initialize inflate output buffer */ + ctx->stream.next_out = ctx->buffer; only in patch2: unchanged: --- apache2-2.2.9.orig/debian/patches/069_fix_mod_rewrite_B_PR45529.dpatch +++ apache2-2.2.9/debian/patches/069_fix_mod_rewrite_B_PR45529.dpatch @@ -0,0 +1,85 @@ +#! /bin/sh /usr/share/dpatch/dpatch-run +## +## All lines beginning with `## DP:' are a description of the patch. +## DP: No description. + +@DPATCH@ +--- a/modules/mappers/mod_rewrite.c (Revision 732577) ++++ b/modules/mappers/mod_rewrite.c (Revision 732578) +@@ -380,6 +380,7 @@ + /* Optional functions imported from mod_ssl when loaded: */ + static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *rewrite_ssl_lookup = NULL; + static APR_OPTIONAL_FN_TYPE(ssl_is_https) *rewrite_is_https = NULL; ++static char *escape_uri(apr_pool_t *p, const char *path); + + /* + * +-------------------------------------------------------+ +@@ -628,7 +629,47 @@ + return 0; + } + ++static const char c2x_table[] = "0123456789abcdef"; ++ ++static APR_INLINE unsigned char *c2x(unsigned what, unsigned char prefix, ++ unsigned char *where) ++{ ++#if APR_CHARSET_EBCDIC ++ what = apr_xlate_conv_byte(ap_hdrs_to_ascii, (unsigned char)what); ++#endif /*APR_CHARSET_EBCDIC*/ ++ *where++ = prefix; ++ *where++ = c2x_table[what >> 4]; ++ *where++ = c2x_table[what & 0xf]; ++ return where; ++} ++ + /* ++ * Escapes a uri in a similar way as php's urlencode does. ++ * Based on ap_os_escape_path in server/util.c ++ */ ++static char *escape_uri(apr_pool_t *p, const char *path) { ++ char *copy = apr_palloc(p, 3 * strlen(path) + 3); ++ const unsigned char *s = (const unsigned char *)path; ++ unsigned char *d = (unsigned char *)copy; ++ unsigned c; ++ ++ while ((c = *s)) { ++ if (apr_isalnum(c) || c == '_') { ++ *d++ = c; ++ } ++ else if (c == ' ') { ++ *d++ = '+'; ++ } ++ else { ++ d = c2x(c, '%', d); ++ } ++ ++s; ++ } ++ *d = '\0'; ++ return copy; ++} ++ ++/* + * escape absolute uri, which may or may not be path oriented. + * So let's handle them differently. + */ +@@ -2240,15 +2281,16 @@ + if (entry && (entry->flags & RULEFLAG_ESCAPEBACKREF)) { + /* escape the backreference */ + char *tmp2, *tmp; +- tmp = apr_pstrndup(pool, bri->source + bri->regmatch[n].rm_so, span); +- tmp2 = ap_escape_path_segment(pool, tmp); ++ tmp = apr_palloc(pool, span + 1); ++ strncpy(tmp, bri->source + bri->regmatch[n].rm_so, span); ++ tmp[span] = '\0'; ++ tmp2 = escape_uri(pool, tmp); + rewritelog((ctx->r, 5, ctx->perdir, "escaping backreference '%s' to '%s'", + tmp, tmp2)); + + current->len = span = strlen(tmp2); + current->string = tmp2; +- } +- else { ++ } else { + current->len = span; + current->string = bri->source + bri->regmatch[n].rm_so; + }