Author: markt
Date: Fri Aug 24 12:31:54 2018
New Revision: 1838836
URL: http://svn.apache.org/viewvc?rev=1838836&view=rev
Log:
Refactor normalisation of request URIs to a common location and align the
normalisation implementation for mod_jk with that implemented by Tomcat.
Modified:
tomcat/jk/trunk/native/apache-2.0/mod_jk.c
tomcat/jk/trunk/native/common/jk_util.c
tomcat/jk/trunk/native/common/jk_util.h
tomcat/jk/trunk/native/iis/jk_isapi_plugin.c
tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
Modified: tomcat/jk/trunk/native/apache-2.0/mod_jk.c
URL:
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/apache-2.0/mod_jk.c?rev=1838836&r1=1838835&r2=1838836&view=diff
==============================================================================
--- tomcat/jk/trunk/native/apache-2.0/mod_jk.c (original)
+++ tomcat/jk/trunk/native/apache-2.0/mod_jk.c Fri Aug 24 12:31:54 2018
@@ -3790,7 +3790,10 @@ static int jk_translate(request_rec * r)
&jk_module);
if (conf) {
+ char *clean_uri;
+ int rc;
const char *worker;
+
if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) {
/* Somebody already set the handler, probably manual config
* or "native" configuration, no need for extra overhead
@@ -3810,6 +3813,12 @@ static int jk_translate(request_rec * r)
return DECLINED;
}
+ clean_uri = apr_pstrdup(r->pool, r->uri);
+ rc = jk_servlet_normalize(clean_uri, conf->log);
+ if (rc != 0) {
+ return HTTP_NOT_FOUND;
+ }
+
/* Special case to make sure that apache can serve a directory
listing if there are no matches for the DirectoryIndex and
Tomcat webapps are mapped into apache using JkAutoAlias. */
@@ -3819,11 +3828,8 @@ static int jk_translate(request_rec * r)
/* Append the request uri to the JkAutoAlias directory and
determine if the file exists. */
- char *clean_uri;
apr_finfo_t finfo;
finfo.filetype = APR_NOFILE;
- clean_uri = apr_pstrdup(r->pool, r->uri);
- ap_no2slash(clean_uri);
/* Map uri to a context static file */
if (strlen(clean_uri) > 1) {
char *context_path = NULL;
@@ -3855,7 +3861,7 @@ static int jk_translate(request_rec * r)
}
else {
rule_extension_t *e;
- worker = map_uri_to_worker_ext(conf->uw_map, r->uri,
+ worker = map_uri_to_worker_ext(conf->uw_map, clean_uri,
NULL, &e, NULL, conf->log);
rconf->rule_extensions = e;
ap_set_module_config(r->request_config, &jk_module, rconf);
@@ -3875,8 +3881,6 @@ static int jk_translate(request_rec * r)
return OK;
}
else if (conf->alias_dir != NULL) {
- char *clean_uri = apr_pstrdup(r->pool, r->uri);
- ap_no2slash(clean_uri);
/* Automatically map uri to a context static file */
if (JK_IS_DEBUG_LEVEL(conf->log))
jk_log(conf->log, JK_LOG_DEBUG,
@@ -3994,7 +3998,10 @@ static int jk_map_to_storage(request_rec
&jk_module);
if (conf) {
+ char *clean_uri;
+ int rc;
const char *worker;
+
if ((r->handler != NULL) && (!strcmp(r->handler, JK_HANDLER))) {
/* Somebody already set the handler, probably manual config
* or "native" configuration, no need for extra overhead
@@ -4013,6 +4020,13 @@ static int jk_map_to_storage(request_rec
return DECLINED;
}
+
+ clean_uri = apr_pstrdup(r->pool, r->uri);
+ rc = jk_servlet_normalize(clean_uri, conf->log);
+ if (rc != 0) {
+ return HTTP_NOT_FOUND;
+ }
+
if (!conf->uw_map) {
if (JK_IS_DEBUG_LEVEL(conf->log))
jk_log(conf->log, JK_LOG_DEBUG,
@@ -4023,7 +4037,7 @@ static int jk_map_to_storage(request_rec
}
else {
rule_extension_t *e;
- worker = map_uri_to_worker_ext(conf->uw_map, r->uri,
+ worker = map_uri_to_worker_ext(conf->uw_map, clean_uri,
NULL, &e, NULL, conf->log);
rconf->rule_extensions = e;
ap_set_module_config(r->request_config, &jk_module, rconf);
Modified: tomcat/jk/trunk/native/common/jk_util.c
URL:
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.c?rev=1838836&r1=1838835&r2=1838836&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_util.c (original)
+++ tomcat/jk/trunk/native/common/jk_util.c Fri Aug 24 12:31:54 2018
@@ -2196,6 +2196,95 @@ void jk_no2slash(char *name)
*d = '\0';
}
+int jk_servlet_normalize(char *path, jk_logger_t *logger)
+{
+ int l, w;
+
+ jk_log(logger, JK_LOG_DEBUG, "URI on entering jk_servlet_normalize: [%s]",
path);
+
+ // This test allows the loops below to start at index 1 rather than 0.
+ if (path[0] != '/') {
+ jk_log(logger, JK_LOG_EMERG, "[%s] does not start with '/'.", path);
+ return JK_NORMALIZE_BAD_PATH;
+ }
+
+ /*
+ * First pass.
+ * Collapse ///// sequences to /
+ */
+ for (l = 1, w = 1; path[l] != '\0';) {
+ if (path[w - 1] == '/' && (path[l] == '/')) {
+ l++;
+ }
+ else
+ path[w++] = path[l++];
+ }
+ path[w] = '\0';
+
+ /* Second pass.
+ * Remove /./ segments including those with path parameters such as
+ * /.;foo=bar/
+ * Both leading and trailing segments will be removed.
+ */
+ for (l = 1, w = 1; path[l] != '\0';) {
+ if (path[l] == '.' &&
+ (path[l + 1] == '/' || path[l + 1] == ';' || path[l + 1] ==
'\0') &&
+ (l == 0 || path[l - 1] == '/')) {
+ l++;
+ while (path[l] != '/' && path[l] != '\0') {
+ l++;
+ }
+ if (path[l] != '\0') {
+ l++;
+ }
+ }
+ else
+ path[w++] = path[l++];
+ }
+ path[w] = '\0';
+
+ /* Third pass.
+ * Remove /xx/../ segments including those with path parameters such as
+ * /xxx/..;foo=bar/
+ * Trailing segments will be removed but leading /../ segments are an error
+ * condition.
+ */
+ for (l = 1, w = 1; path[l] != '\0';) {
+ if (path[l] == '.' && path[l + 1] == '.' &&
+ (path[l + 2] == '/' || path[l + 2] == ';' || path[l + 2] ==
'\0') &&
+ (l == 0 || path[l - 1] == '/')) {
+
+ // Wind w back to remove the previous segment
+ if (w == 1) {
+ jk_log(logger,
+ JK_LOG_EMERG,
+ "[%s] contains a '/../' sequence that tries to escape
above the root.",
+ path);
+ return JK_NORMALIZE_TRAVERSAL;
+ }
+ do {
+ w--;
+ } while (w != 0 && path[w - 1] != '/');
+
+ // Move l forward to the next segment
+ l += 2;
+
+ while (path[l] != '/' && path [l] != '\0') {
+ l++;
+ }
+ if (path[l] != '\0') {
+ l++;
+ }
+ }
+ else
+ path[w++] = path[l++];
+ }
+ path[w] = '\0';
+
+ jk_log(logger, JK_LOG_DEBUG, "URI on exiting jk_servlet_normalize: [%s]",
path);
+ return 0;
+}
+
#ifdef _MT_CODE_PTHREAD
jk_pthread_t jk_gettid()
{
Modified: tomcat/jk/trunk/native/common/jk_util.h
URL:
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/common/jk_util.h?rev=1838836&r1=1838835&r2=1838836&view=diff
==============================================================================
--- tomcat/jk/trunk/native/common/jk_util.h (original)
+++ tomcat/jk/trunk/native/common/jk_util.h Fri Aug 24 12:31:54 2018
@@ -250,6 +250,11 @@ int jk_wildchar_match(const char *str, c
void jk_no2slash(char *name);
+int jk_servlet_normalize(char *path, jk_logger_t *logger);
+
+#define JK_NORMALIZE_BAD_PATH -1
+#define JK_NORMALIZE_TRAVERSAL -2
+
#define TC32_BRIDGE_TYPE 32
#define TC33_BRIDGE_TYPE 33
#define TC40_BRIDGE_TYPE 40
Modified: tomcat/jk/trunk/native/iis/jk_isapi_plugin.c
URL:
http://svn.apache.org/viewvc/tomcat/jk/trunk/native/iis/jk_isapi_plugin.c?rev=1838836&r1=1838835&r2=1838836&view=diff
==============================================================================
--- tomcat/jk/trunk/native/iis/jk_isapi_plugin.c (original)
+++ tomcat/jk/trunk/native/iis/jk_isapi_plugin.c Fri Aug 24 12:31:54 2018
@@ -174,7 +174,6 @@ static char HTTP_WORKER_HEADER_INDEX[RES
#define BAD_REQUEST -1
#define BAD_PATH -2
-#define BAD_NORMALIZATION -3
#define MAX_SERVERNAME 1024
#define MAX_INSTANCEID 32
@@ -660,90 +659,6 @@ static int unescape_url(char *url)
return 0;
}
-static int getparents(char *name)
-{
- int l, w;
-
- jk_log(logger, JK_LOG_DEBUG, "URI on entering getparents: [%s]", name);
-
- // This test allows the loops below to start at index 1 rather than 0.
- if (name[0] != '/') {
- return BAD_PATH;
- }
-
- /*
- * First pass.
- * Collapse ///// sequences to /
- */
- for (l = 1, w = 1; name[l] != '\0';) {
- if (name[w - 1] == '/' && (name[l] == '/')) {
- l++;
- }
- else
- name[w++] = name[l++];
- }
- name[w] = '\0';
-
- /* Second pass.
- * Remove /./ segments including those with path parameters such as
- * /.;foo=bar/
- * Both leading and trailing segments will be removed.
- */
- for (l = 1, w = 1; name[l] != '\0';) {
- if (name[l] == '.' &&
- (name[l + 1] == '/' || name[l + 1] == ';' || name[l +
1] == '\0') &&
- (l == 0 || name[l - 1] == '/')) {
- l++;
- while (name[l] != '/' && name[l] != '\0') {
- l++;
- }
- if (name[l] != '\0') {
- l++;
- }
- }
- else
- name[w++] = name[l++];
- }
- name[w] = '\0';
-
- /* Third pass.
- * Remove /xx/../ segments including those with path parameters such as
- * /xxx/..;foo=bar/
- * Trailing segments will be removed but leading /../ segments are an error
- * condition.
- */
- for (l = 1, w = 1; name[l] != '\0';) {
- if (name[l] == '.' && name[l + 1] == '.' &&
- (name[l + 2] == '/' || name[l + 2] == ';' || name[l +
2] == '\0') &&
- (l == 0 || name[l - 1] == '/')) {
-
- // Wind w back to remove the previous segment
- if (w == 1) {
- return BAD_NORMALIZATION;
- }
- do {
- w--;
- } while (w != 0 && name[w - 1] != '/');
-
- // Move l forward to the next segment
- l += 2;
-
- while (name[l] != '/' && name [l] != '\0') {
- l++;
- }
- if (name[l] != '\0') {
- l++;
- }
- }
- else
- name[w++] = name[l++];
- }
- name[w] = '\0';
-
- jk_log(logger, JK_LOG_DEBUG, "URI on exiting getparents: [%s]", name);
- return 0;
-}
-
/* Apache code to escape a URL */
#define T_OS_ESCAPE_PATH (4)
@@ -1860,19 +1775,7 @@ static DWORD handle_notify_event(PHTTP_F
rv = SF_STATUS_REQ_FINISHED;
goto cleanup;
}
- rc = getparents(uri);
- if (rc == BAD_PATH) {
- jk_log(logger, JK_LOG_EMERG,
- "[%s] does not start with '/'.",
- uri);
- write_error_response(pfc, 404);
- rv = SF_STATUS_REQ_FINISHED;
- goto cleanup;
- }
- if (rc == BAD_NORMALIZATION) {
- jk_log(logger, JK_LOG_EMERG,
- "[%s] contains a '/../' sequence that tries to escape above the
root.",
- uri);
+ if (jk_servlet_normalize(uri, logger)) {
write_error_response(pfc, 404);
rv = SF_STATUS_REQ_FINISHED;
goto cleanup;
@@ -3098,7 +3001,7 @@ static int init_ws_service(isapi_private
JK_TRACE_EXIT(logger);
return JK_FALSE;
}
- getparents(s->req_uri);
+ jk_servlet_normalize(s->req_uri, logger);
} else {
GET_SERVER_VARIABLE_VALUE(HTTP_QUERY_HEADER_NAME, s->query_string, "");
GET_SERVER_VARIABLE_VALUE(HTTP_WORKER_HEADER_NAME, (*worker_name), "");
Modified: tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml?rev=1838836&r1=1838835&r2=1838836&view=diff
==============================================================================
--- tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml (original)
+++ tomcat/jk/trunk/xdocs/miscellaneous/changelog.xml Fri Aug 24 12:31:54 2018
@@ -78,6 +78,11 @@
to improve the control over the number of retries. Based on a patch
provided by Frederik Nosi. (markt)
</add>
+ <fix>
+ Refactor normalisation of request URIs to a common location and align
+ the normalisation implementation for mod_jk with that implemented by
+ Tomcat. (markt)
+ </fix>
</changelog>
</subsection>
</section>
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]