Index: src/CHANGES =================================================================== RCS file: /home/cvs/apache-1.3/src/CHANGES,v retrieving revision 1.1931 diff -u -r1.1931 CHANGES --- src/CHANGES 7 Mar 2004 21:47:13 -0000 1.1931 +++ src/CHANGES 25 Mar 2004 13:54:09 -0000 @@ -1,5 +1,10 @@ Changes with Apache 1.3.30 + *) Fix memory corruption problem with ap_custom_response() function. + The core per-dir config would later point to request pool data + that would be reused for different purposes on different requests. + [Will Lowe, Jeff Trawick] + *) SECURITY: CAN-2003-0993 (cve.mitre.org) Fix parsing of Allow/Deny rules using IP addresses without a netmask; issue is only known to affect big-endian 64-bit Index: src/include/http_core.h =================================================================== RCS file: /home/cvs/apache-1.3/src/include/http_core.h,v retrieving revision 1.73 diff -u -r1.73 http_core.h --- src/include/http_core.h 16 Feb 2004 22:25:08 -0000 1.73 +++ src/include/http_core.h 25 Mar 2004 13:54:10 -0000 @@ -209,7 +209,9 @@ * This lets us do quick merges in merge_core_dir_configs(). */ - char **response_code_strings; + char **response_code_strings; /* from ErrorDocument, not from + * ap_custom_response() + */ /* Hostname resolution etc */ #define HOSTNAME_LOOKUP_OFF 0 Index: src/main/http_core.c =================================================================== RCS file: /home/cvs/apache-1.3/src/main/http_core.c,v retrieving revision 1.331 diff -u -r1.331 http_core.c --- src/main/http_core.c 16 Feb 2004 22:29:33 -0000 1.331 +++ src/main/http_core.c 25 Mar 2004 13:54:13 -0000 @@ -53,6 +53,15 @@ #define MMAP_LIMIT (4*1024*1024) #endif +typedef struct { + /* Custom response strings registered via ap_custom_response(), + * or NULL; check per-dir config if nothing found here + */ + char **response_code_strings; /* from ap_custom_response(), not from + * ErrorDocument + */ +} core_request_config; + /* Server core module... This module provides support for really basic * server operations, including options and commands which control the * operation of other modules. Consider this the bureaucracy module. @@ -580,15 +589,30 @@ API_EXPORT(char *) ap_response_code_string(request_rec *r, int error_index) { - core_dir_config *conf; + core_request_config *reqconf; + core_dir_config *dirconf; - conf = (core_dir_config *)ap_get_module_config(r->per_dir_config, - &core_module); + /* prefer per-request settings, which are created by calls to + * ap_custom_response() + */ + reqconf = (core_request_config *)ap_get_module_config(r->request_config, + &core_module); - if (conf->response_code_strings == NULL) { + if (reqconf != NULL && + reqconf->response_code_strings != NULL && + reqconf->response_code_strings[error_index] != NULL) { + return reqconf->response_code_strings[error_index]; + } + + /* check for string specified via ErrorDocument */ + dirconf = (core_dir_config *)ap_get_module_config(r->per_dir_config, + &core_module); + + if (dirconf->response_code_strings == NULL) { return NULL; } - return conf->response_code_strings[error_index]; + + return dirconf->response_code_strings[error_index]; } @@ -1193,20 +1217,26 @@ API_EXPORT(void) ap_custom_response(request_rec *r, int status, char *string) { - core_dir_config *conf = - ap_get_module_config(r->per_dir_config, &core_module); + core_request_config *reqconf = + ap_get_module_config(r->request_config, &core_module); int idx; - if(conf->response_code_strings == NULL) { - conf->response_code_strings = + if (reqconf == NULL) { + reqconf = (core_request_config *)ap_pcalloc(r->pool, + sizeof(core_request_config)); + ap_set_module_config(r->request_config, &core_module, reqconf); + } + + if (reqconf->response_code_strings == NULL) { + reqconf->response_code_strings = ap_pcalloc(r->pool, - sizeof(*conf->response_code_strings) * - RESPONSE_CODES); + sizeof(reqconf->response_code_strings) * + RESPONSE_CODES); } idx = ap_index_of_response(status); - conf->response_code_strings[idx] = + reqconf->response_code_strings[idx] = ((ap_is_url(string) || (*string == '/')) && (*string != '"')) ? ap_pstrdup(r->pool, string) : ap_pstrcat(r->pool, "\"", string, NULL); }