Hello security team, I have prepared two security updates for libapache-mod-jk which is affected by CVE-2014-8111 [1] in Jessie and Wheezy. This is Debian bug #783233 [2]. I have already packaged a SVN snapshot for sid/stretch. A new upstream release, 1.2.41, has not taken place yet. I am attaching the debdiffs to this e-mail which are identical except that the targeted distributions are different. Therefor I have rebased the upstream fix which can be found here: http://svn.apache.org/r1647017 I think the issue warrants a DSA since it is remotely exploitable although the severity and impact are probably only moderate for most setups. I propose the following text: Package: libapache-mod-jk It was discovered that a JkUnmount rule for a subtree of a previous JkMount rule could be ignored. This could allow a remote attacker to potentially access a private artifact in a tree that would otherwise not be accessible to them. For the oldstable distribution (wheezy), this problem has been fixed in version 1:1.2.37-1+deb7u1. For the stable distribution (jessie), this problem has been fixed in version 1:1.2.37-4+deb8u1. For the testing distribution (stretch), this problem has been fixed in version 1:1.2.40+svn150520-1. For the unstable distribution (sid), this problem has been fixed in version 1:1.2.40+svn150520-1. We recommend that you upgrade your libapache-mod-jk packages. Regards, Markus [1] https://security-tracker.debian.org/tracker/CVE-2014-8111 [2] https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=783233
diff -Nru libapache-mod-jk-1.2.37/debian/changelog libapache-mod-jk-1.2.37/debian/changelog --- libapache-mod-jk-1.2.37/debian/changelog 2014-11-17 14:59:11.000000000 +0100 +++ libapache-mod-jk-1.2.37/debian/changelog 2015-05-23 23:02:08.000000000 +0200 @@ -1,3 +1,21 @@ +libapache-mod-jk (1:1.2.37-4+deb8u1) jessie-security; urgency=high + + * Team upload. + * Add CVE-2014-8111.patch. (Closes: #783233) + It was discovered that a JkUnmount rule for a subtree of a previous JkMount + rule could be ignored. This could allow a remote attacker to potentially + access a private artifact in a tree that would otherwise not be accessible + to them. + - Add option to control handling of multiple adjacent slashes in mount and + unmount. New default is collapsing the slashes only in unmount. Before + this change, adjacent slashes were never collapsed, so most mounts and + unmounts didn't match for URLs with multiple adjacent slashes. + - Configuration is done via new JkOption for Apache + (values "CollapseSlashesAll", "CollapseSlashesNone" or + "CollapseSlashesUnmount"). + + -- Markus Koschany <apo@gambaru.de> Sat, 23 May 2015 01:16:37 +0200 + libapache-mod-jk (1:1.2.37-4) unstable; urgency=medium * Team upload. diff -Nru libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch --- libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch 1970-01-01 01:00:00.000000000 +0100 +++ libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch 2015-05-23 23:02:08.000000000 +0200 @@ -0,0 +1,474 @@ +From: Markus Koschany <apo@gambaru.de> +Date: Sat, 23 May 2015 00:05:21 +0200 +Subject: CVE-2014-8111 + +It was discovered that a JkUnmount rule for a subtree of a previous JkMount rule +could be ignored. This could allow a remote attacker to potentially access a +private artifact in a tree that would otherwise not be accessible to them. + +Forwarded: https://svn.apache.org/viewvc?view=revision&revision=r1647017 +--- + native/apache-1.3/mod_jk.c | 24 +++++++++++++-- + native/apache-2.0/mod_jk.c | 24 +++++++++++++-- + native/common/jk_global.h | 7 ++++- + native/common/jk_uri_worker_map.c | 48 +++++++++++++++++------------ + native/common/jk_uri_worker_map.h | 7 +++++ + native/common/jk_util.c | 19 ++++++++++++ + native/common/jk_util.h | 2 ++ + native/iis/jk_isapi_plugin.c | 64 ++++++++++++++++++++++++++++----------- + 8 files changed, 153 insertions(+), 42 deletions(-) + +diff --git a/native/apache-1.3/mod_jk.c b/native/apache-1.3/mod_jk.c +index 81c3a58..9d6840f 100644 +--- a/native/apache-1.3/mod_jk.c ++++ b/native/apache-1.3/mod_jk.c +@@ -2074,9 +2074,11 @@ const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) + + mask = 0; + +- if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI"))) ++ if (action == '-' && ++ (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || ++ !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) + return ap_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, +- "': ForwardURI* options can not be disabled", NULL); ++ "': option can not be disabled", NULL); + + if (!strcasecmp(w, "ForwardURICompat")) { + opt = JK_OPT_FWDURICOMPAT; +@@ -2094,6 +2096,18 @@ const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) + opt = JK_OPT_FWDURIPROXY; + mask = JK_OPT_FWDURIMASK; + } ++ else if (!strcasecmp(w, "CollapseSlashesAll")) { ++ opt = JK_OPT_COLLAPSEALL; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesNone")) { ++ opt = JK_OPT_COLLAPSENONE; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesUnmount")) { ++ opt = JK_OPT_COLLAPSEUNMOUNT; ++ mask = JK_OPT_COLLAPSEMASK; ++ } + else if (!strcasecmp(w, "ForwardDirectories")) { + opt = JK_OPT_FWDDIRS; + } +@@ -2763,6 +2777,10 @@ static void *merge_jk_config(ap_pool * p, void *basev, void *overridesv) + overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_FWDURIMASK; + else + overrides->options |= (base->options & ~base->exclude_options); ++ if (overrides->options & JK_OPT_COLLAPSEMASK) ++ overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_COLLAPSEMASK; ++ else ++ overrides->options |= (base->options & ~base->exclude_options); + + if (base->envvars) { + if (overrides->envvars && overrides->envvars_has_own) { +@@ -2983,6 +3001,8 @@ static void jk_init(server_rec * s, ap_pool * p) + uri_worker_map_switch(sconf->uw_map, sconf->log); + uri_worker_map_load(sconf->uw_map, sconf->log); + } ++ if (conf->options & JK_OPT_COLLAPSEMASK) ++ sconf->uw_map->collapse_slashes = conf->options & JK_OPT_COLLAPSEMASK; + } + else { + if (sconf->mountcopy == JK_TRUE) { +diff --git a/native/apache-2.0/mod_jk.c b/native/apache-2.0/mod_jk.c +index 7c04440..26345ea 100644 +--- a/native/apache-2.0/mod_jk.c ++++ b/native/apache-2.0/mod_jk.c +@@ -2175,9 +2175,11 @@ static const char *jk_set_options(cmd_parms * cmd, void *dummy, + + mask = 0; + +- if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI"))) ++ if (action == '-' && ++ (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || ++ !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) + return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, +- "': ForwardURI* options can not be disabled", NULL); ++ "': option can not be disabled", NULL); + + if (!strcasecmp(w, "ForwardURICompat")) { + opt = JK_OPT_FWDURICOMPAT; +@@ -2195,6 +2197,18 @@ static const char *jk_set_options(cmd_parms * cmd, void *dummy, + opt = JK_OPT_FWDURIPROXY; + mask = JK_OPT_FWDURIMASK; + } ++ else if (!strcasecmp(w, "CollapseSlashesAll")) { ++ opt = JK_OPT_COLLAPSEALL; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesNone")) { ++ opt = JK_OPT_COLLAPSENONE; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesUnmount")) { ++ opt = JK_OPT_COLLAPSEUNMOUNT; ++ mask = JK_OPT_COLLAPSEMASK; ++ } + else if (!strcasecmp(w, "ForwardDirectories")) { + opt = JK_OPT_FWDDIRS; + } +@@ -2987,6 +3001,10 @@ static void *merge_jk_config(apr_pool_t * p, void *basev, void *overridesv) + overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_FWDURIMASK; + else + overrides->options |= (base->options & ~base->exclude_options); ++ if (overrides->options & JK_OPT_COLLAPSEMASK) ++ overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_COLLAPSEMASK; ++ else ++ overrides->options |= (base->options & ~base->exclude_options); + + if (base->envvars) { + if (overrides->envvars && overrides->envvars_has_own) { +@@ -3464,6 +3482,8 @@ static int jk_post_config(apr_pool_t * pconf, + uri_worker_map_switch(sconf->uw_map, sconf->log); + uri_worker_map_load(sconf->uw_map, sconf->log); + } ++ if (conf->options & JK_OPT_COLLAPSEMASK) ++ sconf->uw_map->collapse_slashes = conf->options & JK_OPT_COLLAPSEMASK; + } + else { + if (sconf->mountcopy == JK_TRUE) { +diff --git a/native/common/jk_global.h b/native/common/jk_global.h +index aefe87e..942ee32 100644 +--- a/native/common/jk_global.h ++++ b/native/common/jk_global.h +@@ -252,6 +252,11 @@ extern "C" + + #define JK_OPT_FWDURIMASK 0x0007 + ++#define JK_OPT_COLLAPSEMASK 0x7000 ++#define JK_OPT_COLLAPSEALL 0x1000 ++#define JK_OPT_COLLAPSENONE 0x2000 ++#define JK_OPT_COLLAPSEUNMOUNT 0x4000 ++ + #define JK_OPT_FWDURICOMPAT 0x0001 + #define JK_OPT_FWDURICOMPATUNPARSED 0x0002 + #define JK_OPT_FWDURIESCAPED 0x0003 +@@ -269,7 +274,7 @@ extern "C" + #define JK_OPT_FWDKEYSIZE 0x0200 + #define JK_OPT_REJECTUNSAFE 0x0400 + +-#define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE) ++#define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE | JK_OPT_COLLAPSEUNMOUNT) + + /* Check for EBCDIC systems */ + +diff --git a/native/common/jk_uri_worker_map.c b/native/common/jk_uri_worker_map.c +index 250cdb5..8c3d44e 100644 +--- a/native/common/jk_uri_worker_map.c ++++ b/native/common/jk_uri_worker_map.c +@@ -174,9 +174,10 @@ static void uri_worker_map_dump(jk_uri_worker_map_t *uw_map, + int i, off; + if (JK_IS_DEBUG_LEVEL(l)) { + jk_log(l, JK_LOG_DEBUG, "uri map dump %s: id=%d, index=%d file='%s' reject_unsafe=%d " +- "reload=%d modified=%d checked=%d", ++ "collapse_slashes=%d reload=%d modified=%d checked=%d", + reason, uw_map->id, uw_map->index, STRNULL_FOR_NULL(uw_map->fname), +- uw_map->reject_unsafe, uw_map->reload, uw_map->modified, uw_map->checked); ++ uw_map->reject_unsafe, uw_map->collapse_slashes, ++ uw_map->reload, uw_map->modified, uw_map->checked); + } + for (i = 0; i <= 1; i++) { + jk_log(l, JK_LOG_DEBUG, "generation %d: size=%d nosize=%d capacity=%d", +@@ -242,6 +243,7 @@ int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map_p, + uw_map->index = 0; + uw_map->fname = NULL; + uw_map->reject_unsafe = 0; ++ uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT; + uw_map->reload = JK_URIMAP_DEF_RELOAD; + uw_map->modified = 0; + uw_map->checked = 0; +@@ -681,48 +683,42 @@ void parse_rule_extensions(char *rule, rule_extension_t *extensions, + else if (!strncmp(param, JK_UWMAP_EXTENSION_ACTIVE, strlen(JK_UWMAP_EXTENSION_ACTIVE))) { + if (extensions->active) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_ACTIVE); ++ "rule extension '" JK_UWMAP_EXTENSION_ACTIVE "' only allowed once"); + else + extensions->active = param + strlen(JK_UWMAP_EXTENSION_ACTIVE); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_DISABLED, strlen(JK_UWMAP_EXTENSION_DISABLED))) { + if (extensions->disabled) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_DISABLED); ++ "rule extension '" JK_UWMAP_EXTENSION_DISABLED "' only allowed once"); + else + extensions->disabled = param + strlen(JK_UWMAP_EXTENSION_DISABLED); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_STOPPED, strlen(JK_UWMAP_EXTENSION_STOPPED))) { + if (extensions->stopped) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_STOPPED); ++ "rule extension '" JK_UWMAP_EXTENSION_STOPPED "' only allowed once"); + else + extensions->stopped = param + strlen(JK_UWMAP_EXTENSION_STOPPED); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_FAIL_ON_STATUS, strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS))) { + if (extensions->fail_on_status_str) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_FAIL_ON_STATUS); ++ "rule extension '" JK_UWMAP_EXTENSION_FAIL_ON_STATUS "' only allowed once"); + else + extensions->fail_on_status_str = param + strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_COOKIE, strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE))) { + if (extensions->session_cookie) + jk_log(l, JK_LOG_WARNING, +- "extension '%s' in uri worker map only allowed once", +- JK_UWMAP_EXTENSION_SESSION_COOKIE); ++ "extension '" JK_UWMAP_EXTENSION_SESSION_COOKIE "' in uri worker map only allowed once"); + else + extensions->session_cookie = param + strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_PATH, strlen(JK_UWMAP_EXTENSION_SESSION_PATH))) { + if (extensions->session_path) + jk_log(l, JK_LOG_WARNING, +- "extension '%s' in uri worker map only allowed once", +- JK_UWMAP_EXTENSION_SESSION_PATH); ++ "extension '" JK_UWMAP_EXTENSION_SESSION_PATH "' in uri worker map only allowed once"); + else { + // Check if the session identifier starts with semicolon. + if (!strcmp(param, JK_UWMAP_EXTENSION_SESSION_PATH)) { +@@ -1034,12 +1030,12 @@ static int is_nomatch(jk_uri_worker_map_t *uw_map, + const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + const char *uri, const char *vhost, + rule_extension_t **extensions, +- int *index, +- jk_logger_t *l) ++ int *index, jk_logger_t *l) + { + unsigned int i; + unsigned int vhost_len; + int reject_unsafe; ++ int collapse_slashes; + int rv = -1; + char url[JK_MAX_URI_LEN+1]; + +@@ -1069,10 +1065,8 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + return NULL; + } + } +- /* Make the copy of the provided uri and strip +- * everything after the first ';' char. +- */ + reject_unsafe = uw_map->reject_unsafe; ++ collapse_slashes = uw_map->collapse_slashes; + vhost_len = 0; + /* + * In case we got a vhost, we prepend a slash +@@ -1100,6 +1094,9 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + } + vhost_len += off; + } ++ /* Make the copy of the provided uri and strip ++ * everything after the first ';' char. ++ */ + for (i = 0; i < strlen(uri); i++) { + if (i == JK_MAX_URI_LEN) { + jk_log(l, JK_LOG_WARNING, +@@ -1127,6 +1124,12 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + jk_log(l, JK_LOG_DEBUG, "Found session identifier '%s' in url '%s'", + url_rewrite, uri); + } ++ if (collapse_slashes == JK_COLLAPSE_ALL) { ++ /* Remove multiple slashes ++ * No need to copy url, because it is local and ++ * the unchanged url is no longer needed */ ++ jk_no2slash(url); ++ } + if (JK_IS_DEBUG_LEVEL(l)) + jk_log(l, JK_LOG_DEBUG, "Attempting to map URI '%s' from %d maps", + url, IND_THIS(uw_map->size)); +@@ -1138,6 +1141,13 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + + /* In case we found a match, check for the unmounts. */ + if (rv >= 0 && IND_THIS(uw_map->nosize)) { ++ if (collapse_slashes == JK_COLLAPSE_UNMOUNT) { ++ /* Remove multiple slashes when looking for ++ * unmount to prevent trivial unmount bypass attack. ++ * No need to copy url, because it is local and ++ * the unchanged url is no longer needed */ ++ jk_no2slash(url); ++ } + /* Again first including vhost. */ + int rc = is_nomatch(uw_map, url, rv, l); + /* If no unmount was find, try without vhost. */ +diff --git a/native/common/jk_uri_worker_map.h b/native/common/jk_uri_worker_map.h +index 1598937..16c14ff 100644 +--- a/native/common/jk_uri_worker_map.h ++++ b/native/common/jk_uri_worker_map.h +@@ -58,6 +58,11 @@ extern "C" + #define MATCH_TYPE_STOPPED 0x4000 + */ + ++#define JK_COLLAPSE_ALL 0x0001 ++#define JK_COLLAPSE_NONE 0x0002 ++#define JK_COLLAPSE_UNMOUNT 0x0003 ++#define JK_COLLAPSE_DEFAULT JK_COLLAPSE_UNMOUNT ++ + #define SOURCE_TYPE_WORKERDEF 0x0001 + #define SOURCE_TYPE_JKMOUNT 0x0002 + #define SOURCE_TYPE_URIMAP 0x0003 +@@ -166,6 +171,8 @@ struct jk_uri_worker_map + JK_CRIT_SEC cs; + /* should we forward potentially unsafe URLs */ + int reject_unsafe; ++ /* how to handle multiple adjacent slashes in URLs */ ++ int collapse_slashes; + /* uriworkermap filename */ + const char *fname; + /* uriworkermap reload check interval */ +diff --git a/native/common/jk_util.c b/native/common/jk_util.c +index 8c5d803..4455f86 100644 +--- a/native/common/jk_util.c ++++ b/native/common/jk_util.c +@@ -2089,6 +2089,25 @@ int jk_wildchar_match(const char *str, const char *exp, int icase) + return (str[x] != '\0'); + } + ++void jk_no2slash(char *name) ++{ ++ char *d, *s; ++ ++ s = d = name; ++ ++ while (*s) { ++ if ((*d++ = *s) == '/') { ++ do { ++ ++s; ++ } while (*s == '/'); ++ } ++ else { ++ ++s; ++ } ++ } ++ *d = '\0'; ++} ++ + #ifdef _MT_CODE_PTHREAD + jk_pthread_t jk_gettid() + { +diff --git a/native/common/jk_util.h b/native/common/jk_util.h +index 2313c2c..930943c 100644 +--- a/native/common/jk_util.h ++++ b/native/common/jk_util.h +@@ -238,6 +238,8 @@ int is_http_status_fail(unsigned int http_status_fail_num, + + int jk_wildchar_match(const char *str, const char *exp, int icase); + ++void jk_no2slash(char *name); ++ + #define TC32_BRIDGE_TYPE 32 + #define TC33_BRIDGE_TYPE 33 + #define TC40_BRIDGE_TYPE 40 +diff --git a/native/iis/jk_isapi_plugin.c b/native/iis/jk_isapi_plugin.c +index e949734..736ac05 100644 +--- a/native/iis/jk_isapi_plugin.c ++++ b/native/iis/jk_isapi_plugin.c +@@ -117,23 +117,27 @@ static char HTTP_WORKER_HEADER_INDEX[RES_BUFFER_SIZE]; + #define W3SVC_REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters" + #define EXTENSION_URI_TAG "extension_uri" + +-#define URI_SELECT_TAG "uri_select" +-#define URI_SELECT_PARSED_VERB "parsed" +-#define URI_SELECT_UNPARSED_VERB "unparsed" +-#define URI_SELECT_ESCAPED_VERB "escaped" +-#define URI_SELECT_PROXY_VERB "proxy" +-#define URI_REWRITE_TAG "rewrite_rule_file" +-#define SHM_SIZE_TAG "shm_size" +-#define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" +-#define STRIP_SESSION_TAG "strip_session" +-#define AUTH_COMPLETE_TAG "auth_complete" +-#define REJECT_UNSAFE_TAG "reject_unsafe" +-#define WATCHDOG_INTERVAL_TAG "watchdog_interval" +-#define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" +-#define ERROR_PAGE_TAG "error_page" +- +-#define LOG_ROTATION_TIME_TAG "log_rotationtime" +-#define LOG_FILESIZE_TAG "log_filesize" ++#define URI_SELECT_TAG "uri_select" ++#define URI_SELECT_PARSED_VERB "parsed" ++#define URI_SELECT_UNPARSED_VERB "unparsed" ++#define URI_SELECT_ESCAPED_VERB "escaped" ++#define URI_SELECT_PROXY_VERB "proxy" ++#define URI_REWRITE_TAG "rewrite_rule_file" ++#define SHM_SIZE_TAG "shm_size" ++#define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" ++#define STRIP_SESSION_TAG "strip_session" ++#define AUTH_COMPLETE_TAG "auth_complete" ++#define REJECT_UNSAFE_TAG "reject_unsafe" ++#define COLLAPSE_SLASHES_TAG "collapse_slashes" ++#define COLLAPSE_SLASHES_ALL_VERB "all" ++#define COLLAPSE_SLASHES_NONE_VERB "none" ++#define COLLAPSE_SLASHES_UNMOUNT_VERB "unmount" ++#define WATCHDOG_INTERVAL_TAG "watchdog_interval" ++#define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" ++#define ERROR_PAGE_TAG "error_page" ++ ++#define LOG_ROTATION_TIME_TAG "log_rotationtime" ++#define LOG_FILESIZE_TAG "log_filesize" + + /* HTTP standard headers */ + #define TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE "Transfer-Encoding: chunked" +@@ -501,6 +505,7 @@ static int strip_session = 0; + static int use_auth_notification_flags = 1; + static int chunked_encoding_enabled = JK_FALSE; + static int reject_unsafe = 0; ++static int collapse_slashes = JK_COLLAPSE_DEFAULT; + static volatile int watchdog_interval = 0; + static HANDLE watchdog_handle = NULL; + static char error_page_buf[INTERNET_MAX_URL_LENGTH] = {0}; +@@ -2791,6 +2796,7 @@ static int init_jk(char *serverName) + uw_map->reject_unsafe = 1; + else + uw_map->reject_unsafe = 0; ++ uw_map->collapse_slashes = collapse_slashes; + uw_map->reload = worker_mount_reload; + if (worker_mount_file[0]) { + uw_map->fname = worker_mount_file; +@@ -2920,6 +2926,17 @@ int parse_uri_select(const char *uri_select) + return -1; + } + ++int parse_collapse_slashes(const char *collapse_slashes) ++{ ++ if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_ALL_VERB)) ++ return JK_OPT_COLLAPSEALL; ++ if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_NONE_VERB)) ++ return JK_OPT_COLLAPSENONE; ++ if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_UNMOUNT_VERB)) ++ return JK_OPT_COLLAPSEUNMOUNT; ++ return -1; ++} ++ + static int read_registry_init_data(void) + { + char tmpbuf[MAX_PATH]; +@@ -3017,7 +3034,18 @@ static int read_registry_init_data(void) + uri_select_option = opt; + } + else { +- goto cleanup; ++ jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" ++ URI_SELECT_TAG "'", tmpbuf); ++ } ++ } ++ if (get_config_parameter(src, COLLAPSE_SLASHES_TAG, tmpbuf, sizeof(tmpbuf))) { ++ int opt = parse_collapse_slashes(tmpbuf); ++ if (opt >= 0) { ++ collapse_slashes = opt; ++ } ++ else { ++ jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" ++ COLLAPSE_SLASHES_TAG "'", tmpbuf); + } + } + shm_config_size = get_config_int(src, SHM_SIZE_TAG, -1); diff -Nru libapache-mod-jk-1.2.37/debian/patches/series libapache-mod-jk-1.2.37/debian/patches/series --- libapache-mod-jk-1.2.37/debian/patches/series 2014-11-17 14:59:11.000000000 +0100 +++ libapache-mod-jk-1.2.37/debian/patches/series 2015-05-23 23:02:08.000000000 +0200 @@ -2,3 +2,4 @@ 0002-debianize-log-directory.patch 0003-upgrade-info-to-error-message.patch 0004-corrupted-worker-activation-status.patch +CVE-2014-8111.patch
diff -Nru libapache-mod-jk-1.2.37/debian/changelog libapache-mod-jk-1.2.37/debian/changelog --- libapache-mod-jk-1.2.37/debian/changelog 2012-06-03 23:09:48.000000000 +0200 +++ libapache-mod-jk-1.2.37/debian/changelog 2015-05-23 23:36:08.000000000 +0200 @@ -1,3 +1,20 @@ +libapache-mod-jk (1:1.2.37-1+deb7u1) wheezy-security; urgency=high + + * Team upload. + * Add CVE-2014-8111.patch. (Closes: #783233) + It was discovered that a JkUnmount rule for a subtree of a previous JkMount + rule could be ignored. This could allow a remote attacker to potentially + access a private artifact in a tree that would otherwise not be accessible + to them. + - Add option to control handling of multiple adjacent slashes in mount and + unmount. New default is collapsing the slashes only in unmount. Before + this change, adjacent slashes were never collapsed, so most mounts and + unmounts didn't match for URLs with multiple adjacent slashes. + - Configuration is done via new JkOption for Apache (values + "CollapseSlashesAll", "CollapseSlashesNone" or "CollapseSlashesUnmount"). + + -- Markus Koschany <apo@gambaru.de> Sat, 23 May 2015 23:33:30 +0200 + libapache-mod-jk (1:1.2.37-1) unstable; urgency=low * New upstream release. diff -Nru libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch --- libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch 1970-01-01 01:00:00.000000000 +0100 +++ libapache-mod-jk-1.2.37/debian/patches/CVE-2014-8111.patch 2015-05-23 23:36:08.000000000 +0200 @@ -0,0 +1,474 @@ +From: Markus Koschany <apo@gambaru.de> +Date: Sat, 23 May 2015 00:05:21 +0200 +Subject: CVE-2014-8111 + +It was discovered that a JkUnmount rule for a subtree of a previous JkMount rule +could be ignored. This could allow a remote attacker to potentially access a +private artifact in a tree that would otherwise not be accessible to them. + +Forwarded: https://svn.apache.org/viewvc?view=revision&revision=r1647017 +--- + native/apache-1.3/mod_jk.c | 24 +++++++++++++-- + native/apache-2.0/mod_jk.c | 24 +++++++++++++-- + native/common/jk_global.h | 7 ++++- + native/common/jk_uri_worker_map.c | 48 +++++++++++++++++------------ + native/common/jk_uri_worker_map.h | 7 +++++ + native/common/jk_util.c | 19 ++++++++++++ + native/common/jk_util.h | 2 ++ + native/iis/jk_isapi_plugin.c | 64 ++++++++++++++++++++++++++++----------- + 8 files changed, 153 insertions(+), 42 deletions(-) + +diff --git a/native/apache-1.3/mod_jk.c b/native/apache-1.3/mod_jk.c +index 81c3a58..9d6840f 100644 +--- a/native/apache-1.3/mod_jk.c ++++ b/native/apache-1.3/mod_jk.c +@@ -2074,9 +2074,11 @@ const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) + + mask = 0; + +- if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI"))) ++ if (action == '-' && ++ (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || ++ !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) + return ap_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, +- "': ForwardURI* options can not be disabled", NULL); ++ "': option can not be disabled", NULL); + + if (!strcasecmp(w, "ForwardURICompat")) { + opt = JK_OPT_FWDURICOMPAT; +@@ -2094,6 +2096,18 @@ const char *jk_set_options(cmd_parms * cmd, void *dummy, const char *line) + opt = JK_OPT_FWDURIPROXY; + mask = JK_OPT_FWDURIMASK; + } ++ else if (!strcasecmp(w, "CollapseSlashesAll")) { ++ opt = JK_OPT_COLLAPSEALL; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesNone")) { ++ opt = JK_OPT_COLLAPSENONE; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesUnmount")) { ++ opt = JK_OPT_COLLAPSEUNMOUNT; ++ mask = JK_OPT_COLLAPSEMASK; ++ } + else if (!strcasecmp(w, "ForwardDirectories")) { + opt = JK_OPT_FWDDIRS; + } +@@ -2763,6 +2777,10 @@ static void *merge_jk_config(ap_pool * p, void *basev, void *overridesv) + overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_FWDURIMASK; + else + overrides->options |= (base->options & ~base->exclude_options); ++ if (overrides->options & JK_OPT_COLLAPSEMASK) ++ overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_COLLAPSEMASK; ++ else ++ overrides->options |= (base->options & ~base->exclude_options); + + if (base->envvars) { + if (overrides->envvars && overrides->envvars_has_own) { +@@ -2983,6 +3001,8 @@ static void jk_init(server_rec * s, ap_pool * p) + uri_worker_map_switch(sconf->uw_map, sconf->log); + uri_worker_map_load(sconf->uw_map, sconf->log); + } ++ if (conf->options & JK_OPT_COLLAPSEMASK) ++ sconf->uw_map->collapse_slashes = conf->options & JK_OPT_COLLAPSEMASK; + } + else { + if (sconf->mountcopy == JK_TRUE) { +diff --git a/native/apache-2.0/mod_jk.c b/native/apache-2.0/mod_jk.c +index 7c04440..26345ea 100644 +--- a/native/apache-2.0/mod_jk.c ++++ b/native/apache-2.0/mod_jk.c +@@ -2175,9 +2175,11 @@ static const char *jk_set_options(cmd_parms * cmd, void *dummy, + + mask = 0; + +- if (action == '-' && !strncasecmp(w, "ForwardURI", strlen("ForwardURI"))) ++ if (action == '-' && ++ (!strncasecmp(w, "ForwardURI", strlen("ForwardURI")) || ++ !strncasecmp(w, "CollapseSlashes", strlen("CollapseSlashes")))) + return apr_pstrcat(cmd->pool, "JkOptions: Illegal option '-", w, +- "': ForwardURI* options can not be disabled", NULL); ++ "': option can not be disabled", NULL); + + if (!strcasecmp(w, "ForwardURICompat")) { + opt = JK_OPT_FWDURICOMPAT; +@@ -2195,6 +2197,18 @@ static const char *jk_set_options(cmd_parms * cmd, void *dummy, + opt = JK_OPT_FWDURIPROXY; + mask = JK_OPT_FWDURIMASK; + } ++ else if (!strcasecmp(w, "CollapseSlashesAll")) { ++ opt = JK_OPT_COLLAPSEALL; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesNone")) { ++ opt = JK_OPT_COLLAPSENONE; ++ mask = JK_OPT_COLLAPSEMASK; ++ } ++ else if (!strcasecmp(w, "CollapseSlashesUnmount")) { ++ opt = JK_OPT_COLLAPSEUNMOUNT; ++ mask = JK_OPT_COLLAPSEMASK; ++ } + else if (!strcasecmp(w, "ForwardDirectories")) { + opt = JK_OPT_FWDDIRS; + } +@@ -2987,6 +3001,10 @@ static void *merge_jk_config(apr_pool_t * p, void *basev, void *overridesv) + overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_FWDURIMASK; + else + overrides->options |= (base->options & ~base->exclude_options); ++ if (overrides->options & JK_OPT_COLLAPSEMASK) ++ overrides->options |= (base->options & ~base->exclude_options) & ~JK_OPT_COLLAPSEMASK; ++ else ++ overrides->options |= (base->options & ~base->exclude_options); + + if (base->envvars) { + if (overrides->envvars && overrides->envvars_has_own) { +@@ -3464,6 +3482,8 @@ static int jk_post_config(apr_pool_t * pconf, + uri_worker_map_switch(sconf->uw_map, sconf->log); + uri_worker_map_load(sconf->uw_map, sconf->log); + } ++ if (conf->options & JK_OPT_COLLAPSEMASK) ++ sconf->uw_map->collapse_slashes = conf->options & JK_OPT_COLLAPSEMASK; + } + else { + if (sconf->mountcopy == JK_TRUE) { +diff --git a/native/common/jk_global.h b/native/common/jk_global.h +index aefe87e..942ee32 100644 +--- a/native/common/jk_global.h ++++ b/native/common/jk_global.h +@@ -252,6 +252,11 @@ extern "C" + + #define JK_OPT_FWDURIMASK 0x0007 + ++#define JK_OPT_COLLAPSEMASK 0x7000 ++#define JK_OPT_COLLAPSEALL 0x1000 ++#define JK_OPT_COLLAPSENONE 0x2000 ++#define JK_OPT_COLLAPSEUNMOUNT 0x4000 ++ + #define JK_OPT_FWDURICOMPAT 0x0001 + #define JK_OPT_FWDURICOMPATUNPARSED 0x0002 + #define JK_OPT_FWDURIESCAPED 0x0003 +@@ -269,7 +274,7 @@ extern "C" + #define JK_OPT_FWDKEYSIZE 0x0200 + #define JK_OPT_REJECTUNSAFE 0x0400 + +-#define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE) ++#define JK_OPT_DEFAULT (JK_OPT_FWDURIDEFAULT | JK_OPT_FWDKEYSIZE | JK_OPT_COLLAPSEUNMOUNT) + + /* Check for EBCDIC systems */ + +diff --git a/native/common/jk_uri_worker_map.c b/native/common/jk_uri_worker_map.c +index 250cdb5..8c3d44e 100644 +--- a/native/common/jk_uri_worker_map.c ++++ b/native/common/jk_uri_worker_map.c +@@ -174,9 +174,10 @@ static void uri_worker_map_dump(jk_uri_worker_map_t *uw_map, + int i, off; + if (JK_IS_DEBUG_LEVEL(l)) { + jk_log(l, JK_LOG_DEBUG, "uri map dump %s: id=%d, index=%d file='%s' reject_unsafe=%d " +- "reload=%d modified=%d checked=%d", ++ "collapse_slashes=%d reload=%d modified=%d checked=%d", + reason, uw_map->id, uw_map->index, STRNULL_FOR_NULL(uw_map->fname), +- uw_map->reject_unsafe, uw_map->reload, uw_map->modified, uw_map->checked); ++ uw_map->reject_unsafe, uw_map->collapse_slashes, ++ uw_map->reload, uw_map->modified, uw_map->checked); + } + for (i = 0; i <= 1; i++) { + jk_log(l, JK_LOG_DEBUG, "generation %d: size=%d nosize=%d capacity=%d", +@@ -242,6 +243,7 @@ int uri_worker_map_alloc(jk_uri_worker_map_t **uw_map_p, + uw_map->index = 0; + uw_map->fname = NULL; + uw_map->reject_unsafe = 0; ++ uw_map->collapse_slashes = JK_COLLAPSE_DEFAULT; + uw_map->reload = JK_URIMAP_DEF_RELOAD; + uw_map->modified = 0; + uw_map->checked = 0; +@@ -681,48 +683,42 @@ void parse_rule_extensions(char *rule, rule_extension_t *extensions, + else if (!strncmp(param, JK_UWMAP_EXTENSION_ACTIVE, strlen(JK_UWMAP_EXTENSION_ACTIVE))) { + if (extensions->active) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_ACTIVE); ++ "rule extension '" JK_UWMAP_EXTENSION_ACTIVE "' only allowed once"); + else + extensions->active = param + strlen(JK_UWMAP_EXTENSION_ACTIVE); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_DISABLED, strlen(JK_UWMAP_EXTENSION_DISABLED))) { + if (extensions->disabled) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_DISABLED); ++ "rule extension '" JK_UWMAP_EXTENSION_DISABLED "' only allowed once"); + else + extensions->disabled = param + strlen(JK_UWMAP_EXTENSION_DISABLED); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_STOPPED, strlen(JK_UWMAP_EXTENSION_STOPPED))) { + if (extensions->stopped) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_STOPPED); ++ "rule extension '" JK_UWMAP_EXTENSION_STOPPED "' only allowed once"); + else + extensions->stopped = param + strlen(JK_UWMAP_EXTENSION_STOPPED); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_FAIL_ON_STATUS, strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS))) { + if (extensions->fail_on_status_str) + jk_log(l, JK_LOG_WARNING, +- "rule extension '%s' only allowed once", +- JK_UWMAP_EXTENSION_FAIL_ON_STATUS); ++ "rule extension '" JK_UWMAP_EXTENSION_FAIL_ON_STATUS "' only allowed once"); + else + extensions->fail_on_status_str = param + strlen(JK_UWMAP_EXTENSION_FAIL_ON_STATUS); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_COOKIE, strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE))) { + if (extensions->session_cookie) + jk_log(l, JK_LOG_WARNING, +- "extension '%s' in uri worker map only allowed once", +- JK_UWMAP_EXTENSION_SESSION_COOKIE); ++ "extension '" JK_UWMAP_EXTENSION_SESSION_COOKIE "' in uri worker map only allowed once"); + else + extensions->session_cookie = param + strlen(JK_UWMAP_EXTENSION_SESSION_COOKIE); + } + else if (!strncmp(param, JK_UWMAP_EXTENSION_SESSION_PATH, strlen(JK_UWMAP_EXTENSION_SESSION_PATH))) { + if (extensions->session_path) + jk_log(l, JK_LOG_WARNING, +- "extension '%s' in uri worker map only allowed once", +- JK_UWMAP_EXTENSION_SESSION_PATH); ++ "extension '" JK_UWMAP_EXTENSION_SESSION_PATH "' in uri worker map only allowed once"); + else { + // Check if the session identifier starts with semicolon. + if (!strcmp(param, JK_UWMAP_EXTENSION_SESSION_PATH)) { +@@ -1034,12 +1030,12 @@ static int is_nomatch(jk_uri_worker_map_t *uw_map, + const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + const char *uri, const char *vhost, + rule_extension_t **extensions, +- int *index, +- jk_logger_t *l) ++ int *index, jk_logger_t *l) + { + unsigned int i; + unsigned int vhost_len; + int reject_unsafe; ++ int collapse_slashes; + int rv = -1; + char url[JK_MAX_URI_LEN+1]; + +@@ -1069,10 +1065,8 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + return NULL; + } + } +- /* Make the copy of the provided uri and strip +- * everything after the first ';' char. +- */ + reject_unsafe = uw_map->reject_unsafe; ++ collapse_slashes = uw_map->collapse_slashes; + vhost_len = 0; + /* + * In case we got a vhost, we prepend a slash +@@ -1100,6 +1094,9 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + } + vhost_len += off; + } ++ /* Make the copy of the provided uri and strip ++ * everything after the first ';' char. ++ */ + for (i = 0; i < strlen(uri); i++) { + if (i == JK_MAX_URI_LEN) { + jk_log(l, JK_LOG_WARNING, +@@ -1127,6 +1124,12 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + jk_log(l, JK_LOG_DEBUG, "Found session identifier '%s' in url '%s'", + url_rewrite, uri); + } ++ if (collapse_slashes == JK_COLLAPSE_ALL) { ++ /* Remove multiple slashes ++ * No need to copy url, because it is local and ++ * the unchanged url is no longer needed */ ++ jk_no2slash(url); ++ } + if (JK_IS_DEBUG_LEVEL(l)) + jk_log(l, JK_LOG_DEBUG, "Attempting to map URI '%s' from %d maps", + url, IND_THIS(uw_map->size)); +@@ -1138,6 +1141,13 @@ const char *map_uri_to_worker_ext(jk_uri_worker_map_t *uw_map, + + /* In case we found a match, check for the unmounts. */ + if (rv >= 0 && IND_THIS(uw_map->nosize)) { ++ if (collapse_slashes == JK_COLLAPSE_UNMOUNT) { ++ /* Remove multiple slashes when looking for ++ * unmount to prevent trivial unmount bypass attack. ++ * No need to copy url, because it is local and ++ * the unchanged url is no longer needed */ ++ jk_no2slash(url); ++ } + /* Again first including vhost. */ + int rc = is_nomatch(uw_map, url, rv, l); + /* If no unmount was find, try without vhost. */ +diff --git a/native/common/jk_uri_worker_map.h b/native/common/jk_uri_worker_map.h +index 1598937..16c14ff 100644 +--- a/native/common/jk_uri_worker_map.h ++++ b/native/common/jk_uri_worker_map.h +@@ -58,6 +58,11 @@ extern "C" + #define MATCH_TYPE_STOPPED 0x4000 + */ + ++#define JK_COLLAPSE_ALL 0x0001 ++#define JK_COLLAPSE_NONE 0x0002 ++#define JK_COLLAPSE_UNMOUNT 0x0003 ++#define JK_COLLAPSE_DEFAULT JK_COLLAPSE_UNMOUNT ++ + #define SOURCE_TYPE_WORKERDEF 0x0001 + #define SOURCE_TYPE_JKMOUNT 0x0002 + #define SOURCE_TYPE_URIMAP 0x0003 +@@ -166,6 +171,8 @@ struct jk_uri_worker_map + JK_CRIT_SEC cs; + /* should we forward potentially unsafe URLs */ + int reject_unsafe; ++ /* how to handle multiple adjacent slashes in URLs */ ++ int collapse_slashes; + /* uriworkermap filename */ + const char *fname; + /* uriworkermap reload check interval */ +diff --git a/native/common/jk_util.c b/native/common/jk_util.c +index 8c5d803..4455f86 100644 +--- a/native/common/jk_util.c ++++ b/native/common/jk_util.c +@@ -2089,6 +2089,25 @@ int jk_wildchar_match(const char *str, const char *exp, int icase) + return (str[x] != '\0'); + } + ++void jk_no2slash(char *name) ++{ ++ char *d, *s; ++ ++ s = d = name; ++ ++ while (*s) { ++ if ((*d++ = *s) == '/') { ++ do { ++ ++s; ++ } while (*s == '/'); ++ } ++ else { ++ ++s; ++ } ++ } ++ *d = '\0'; ++} ++ + #ifdef _MT_CODE_PTHREAD + jk_pthread_t jk_gettid() + { +diff --git a/native/common/jk_util.h b/native/common/jk_util.h +index 2313c2c..930943c 100644 +--- a/native/common/jk_util.h ++++ b/native/common/jk_util.h +@@ -238,6 +238,8 @@ int is_http_status_fail(unsigned int http_status_fail_num, + + int jk_wildchar_match(const char *str, const char *exp, int icase); + ++void jk_no2slash(char *name); ++ + #define TC32_BRIDGE_TYPE 32 + #define TC33_BRIDGE_TYPE 33 + #define TC40_BRIDGE_TYPE 40 +diff --git a/native/iis/jk_isapi_plugin.c b/native/iis/jk_isapi_plugin.c +index e949734..736ac05 100644 +--- a/native/iis/jk_isapi_plugin.c ++++ b/native/iis/jk_isapi_plugin.c +@@ -117,23 +117,27 @@ static char HTTP_WORKER_HEADER_INDEX[RES_BUFFER_SIZE]; + #define W3SVC_REGISTRY_KEY "SYSTEM\\CurrentControlSet\\Services\\W3SVC\\Parameters" + #define EXTENSION_URI_TAG "extension_uri" + +-#define URI_SELECT_TAG "uri_select" +-#define URI_SELECT_PARSED_VERB "parsed" +-#define URI_SELECT_UNPARSED_VERB "unparsed" +-#define URI_SELECT_ESCAPED_VERB "escaped" +-#define URI_SELECT_PROXY_VERB "proxy" +-#define URI_REWRITE_TAG "rewrite_rule_file" +-#define SHM_SIZE_TAG "shm_size" +-#define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" +-#define STRIP_SESSION_TAG "strip_session" +-#define AUTH_COMPLETE_TAG "auth_complete" +-#define REJECT_UNSAFE_TAG "reject_unsafe" +-#define WATCHDOG_INTERVAL_TAG "watchdog_interval" +-#define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" +-#define ERROR_PAGE_TAG "error_page" +- +-#define LOG_ROTATION_TIME_TAG "log_rotationtime" +-#define LOG_FILESIZE_TAG "log_filesize" ++#define URI_SELECT_TAG "uri_select" ++#define URI_SELECT_PARSED_VERB "parsed" ++#define URI_SELECT_UNPARSED_VERB "unparsed" ++#define URI_SELECT_ESCAPED_VERB "escaped" ++#define URI_SELECT_PROXY_VERB "proxy" ++#define URI_REWRITE_TAG "rewrite_rule_file" ++#define SHM_SIZE_TAG "shm_size" ++#define WORKER_MOUNT_RELOAD_TAG "worker_mount_reload" ++#define STRIP_SESSION_TAG "strip_session" ++#define AUTH_COMPLETE_TAG "auth_complete" ++#define REJECT_UNSAFE_TAG "reject_unsafe" ++#define COLLAPSE_SLASHES_TAG "collapse_slashes" ++#define COLLAPSE_SLASHES_ALL_VERB "all" ++#define COLLAPSE_SLASHES_NONE_VERB "none" ++#define COLLAPSE_SLASHES_UNMOUNT_VERB "unmount" ++#define WATCHDOG_INTERVAL_TAG "watchdog_interval" ++#define ENABLE_CHUNKED_ENCODING_TAG "enable_chunked_encoding" ++#define ERROR_PAGE_TAG "error_page" ++ ++#define LOG_ROTATION_TIME_TAG "log_rotationtime" ++#define LOG_FILESIZE_TAG "log_filesize" + + /* HTTP standard headers */ + #define TRANSFER_ENCODING_CHUNKED_HEADER_COMPLETE "Transfer-Encoding: chunked" +@@ -501,6 +505,7 @@ static int strip_session = 0; + static int use_auth_notification_flags = 1; + static int chunked_encoding_enabled = JK_FALSE; + static int reject_unsafe = 0; ++static int collapse_slashes = JK_COLLAPSE_DEFAULT; + static volatile int watchdog_interval = 0; + static HANDLE watchdog_handle = NULL; + static char error_page_buf[INTERNET_MAX_URL_LENGTH] = {0}; +@@ -2791,6 +2796,7 @@ static int init_jk(char *serverName) + uw_map->reject_unsafe = 1; + else + uw_map->reject_unsafe = 0; ++ uw_map->collapse_slashes = collapse_slashes; + uw_map->reload = worker_mount_reload; + if (worker_mount_file[0]) { + uw_map->fname = worker_mount_file; +@@ -2920,6 +2926,17 @@ int parse_uri_select(const char *uri_select) + return -1; + } + ++int parse_collapse_slashes(const char *collapse_slashes) ++{ ++ if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_ALL_VERB)) ++ return JK_OPT_COLLAPSEALL; ++ if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_NONE_VERB)) ++ return JK_OPT_COLLAPSENONE; ++ if (!strcasecmp(collapse_slashes, COLLAPSE_SLASHES_UNMOUNT_VERB)) ++ return JK_OPT_COLLAPSEUNMOUNT; ++ return -1; ++} ++ + static int read_registry_init_data(void) + { + char tmpbuf[MAX_PATH]; +@@ -3017,7 +3034,18 @@ static int read_registry_init_data(void) + uri_select_option = opt; + } + else { +- goto cleanup; ++ jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" ++ URI_SELECT_TAG "'", tmpbuf); ++ } ++ } ++ if (get_config_parameter(src, COLLAPSE_SLASHES_TAG, tmpbuf, sizeof(tmpbuf))) { ++ int opt = parse_collapse_slashes(tmpbuf); ++ if (opt >= 0) { ++ collapse_slashes = opt; ++ } ++ else { ++ jk_log(logger, JK_LOG_ERROR, "Invalid value '%s' for configuration item '" ++ COLLAPSE_SLASHES_TAG "'", tmpbuf); + } + } + shm_config_size = get_config_int(src, SHM_SIZE_TAG, -1); diff -Nru libapache-mod-jk-1.2.37/debian/patches/series libapache-mod-jk-1.2.37/debian/patches/series --- libapache-mod-jk-1.2.37/debian/patches/series 2012-04-04 22:34:09.000000000 +0200 +++ libapache-mod-jk-1.2.37/debian/patches/series 2015-05-23 23:36:08.000000000 +0200 @@ -1,3 +1,4 @@ 0001-disable-logo.patch 0002-debianize-log-directory.patch 0003-upgrade-info-to-error-message.patch +CVE-2014-8111.patch
Attachment:
signature.asc
Description: OpenPGP digital signature