@@ -9206,13 +9206,17 @@ static int wsgi_start_process(apr_pool_t *p, WSGIDaemonProcess *daemon)
92069206 }
92079207
92089208 if (daemon -> group -> locale ) {
9209+ char * envvar ;
92099210 char * result ;
92109211
92119212 ap_log_error (APLOG_MARK , APLOG_DEBUG , 0 , wsgi_server ,
92129213 "mod_wsgi (pid=%d): Setting locale to %s for "
92139214 "daemon process group %s." , getpid (),
92149215 daemon -> group -> locale , daemon -> group -> name );
92159216
9217+ envvar = apr_pstrcat (p , "LC_ALL=" , daemon -> group -> locale , NULL );
9218+ putenv (envvar );
9219+
92169220 result = setlocale (LC_ALL , daemon -> group -> locale );
92179221
92189222 if (!result ) {
@@ -11368,6 +11372,27 @@ static apr_status_t wsgi_header_filter(ap_filter_t *f, apr_bucket_brigade *b)
1136811372 return ap_pass_brigade (f -> next , b );
1136911373}
1137011374
11375+ typedef struct cve_2013_5704_fields cve_2013_5704_fields ;
11376+ typedef struct cve_2013_5704_apache22 cve_2013_5704_apache22 ;
11377+ typedef struct cve_2013_5704_apache24 cve_2013_5704_apache24 ;
11378+
11379+ struct cve_2013_5704_fields {
11380+ apr_table_t * trailers_in ;
11381+ apr_table_t * trailers_out ;
11382+ };
11383+
11384+ struct cve_2013_5704_apache22 {
11385+ struct ap_filter_t * proto_input_filters ;
11386+ int eos_sent ;
11387+ cve_2013_5704_fields fields ;
11388+ };
11389+
11390+ struct cve_2013_5704_apache24 {
11391+ apr_sockaddr_t * useragent_addr ;
11392+ char * useragent_ip ;
11393+ cve_2013_5704_fields fields ;
11394+ };
11395+
1137111396static int wsgi_hook_daemon_handler (conn_rec * c )
1137211397{
1137311398 apr_socket_t * csd ;
@@ -11397,6 +11422,13 @@ static int wsgi_hook_daemon_handler(conn_rec *c)
1139711422
1139811423 int queue_timeout_occurred = 0 ;
1139911424
11425+ #if ! (AP_MODULE_MAGIC_AT_LEAST (20120211 , 37 ) || \
11426+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && \
11427+ AP_SERVER_MINORVERSION_NUMBER <= 2 && \
11428+ AP_MODULE_MAGIC_AT_LEAST (20051115 , 36 )))
11429+ apr_size_t size = 0 ;
11430+ #endif
11431+
1140011432 /* Don't do anything if not in daemon process. */
1140111433
1140211434 if (!wsgi_daemon_pool )
@@ -11450,10 +11482,22 @@ static int wsgi_hook_daemon_handler(conn_rec *c)
1145011482 next = current -> next ;
1145111483 }
1145211484
11453- /* Create and populate our own request object. */
11485+ /*
11486+ * Create and populate our own request object. We allocate more
11487+ * memory than we require here for the request_rec in order to
11488+ * implement an opimistic hack for the case where mod_wsgi is built
11489+ * against an Apache version prior to CVE-2013-6704 being applied to
11490+ * it. If that Apache is upgraded but mod_wsgi not recompiled then
11491+ * it will crash in daemon mode. We therefore use the extra space to
11492+ * set the structure members which are added by CVE-2013-6704 to try
11493+ * and avoid that situation. Note that this is distinct from the
11494+ * hack down below to deal with where mod_wsgi was compiled against
11495+ * an Apache version which had CVE-2013-6704 backported.
11496+ */
1145411497
1145511498 apr_pool_create (& p , c -> pool );
11456- r = apr_pcalloc (p , sizeof (request_rec ));
11499+
11500+ r = apr_pcalloc (p , sizeof (request_rec )+ sizeof (cve_2013_5704_fields ));
1145711501
1145811502 r -> pool = p ;
1145911503 r -> connection = c ;
@@ -11477,6 +11521,78 @@ static int wsgi_hook_daemon_handler(conn_rec *c)
1147711521 r -> proto_input_filters = c -> input_filters ;
1147811522 r -> input_filters = r -> proto_input_filters ;
1147911523
11524+ #if AP_MODULE_MAGIC_AT_LEAST (20120211 , 37 ) || \
11525+ (AP_SERVER_MAJORVERSION_NUMBER == 2 && \
11526+ AP_SERVER_MINORVERSION_NUMBER <= 2 && \
11527+ AP_MODULE_MAGIC_AT_LEAST (20051115 , 36 ))
11528+
11529+ /*
11530+ * New request_rec fields were added to Apache because of changes
11531+ * related to CVE-2013-5704. The change means that mod_wsgi version
11532+ * 4.4.0-4.4.5 will crash if run on the Apache versions with the
11533+ * addition fields if mod_wsgi daemon mode is used. If we are using
11534+ * Apache 2.2.29 or 2.4.11, we set the fields direct against the
11535+ * new structure members.
11536+ */
11537+
11538+ r -> trailers_in = apr_table_make (r -> pool , 5 );
11539+ r -> trailers_out = apr_table_make (r -> pool , 5 );
11540+ #else
11541+ /*
11542+ * We use a huge hack here to try and identify when CVE-2013-5704
11543+ * has been back ported to older Apache version. This is necessary
11544+ * as when backported the Apache module magic number will not be
11545+ * updated and it isn't possible to determine from that at compile
11546+ * time if the new structure members exist and so that they should
11547+ * be set. We therefore try and work out whether the extra structure
11548+ * members exist through looking at the size of request_rec and
11549+ * whether memory has been allocated above what is known to be the
11550+ * last member in the structure before the new members were added.
11551+ */
11552+
11553+ #if AP_SERVER_MINORVERSION_NUMBER <= 2
11554+ size = offsetof(request_rec , eos_sent );
11555+ size += sizeof (r -> eos_sent );
11556+ #else
11557+ size = offsetof(request_rec , useragent_ip );
11558+ size += sizeof (r -> useragent_ip );
11559+ #endif
11560+
11561+ /*
11562+ * Check whether request_rec is at least as large as minimal size
11563+ * plus the size of the extra fields. If it is, then we need to
11564+ * set the additional fields.
11565+ */
11566+
11567+ if (sizeof (request_rec ) >= size + sizeof (cve_2013_5704_fields )) {
11568+ #if AP_SERVER_MINORVERSION_NUMBER <= 2
11569+ cve_2013_5704_apache22 * rext ;
11570+ rext = (cve_2013_5704_apache22 * )& r -> proto_input_filters ;
11571+ #else
11572+ cve_2013_5704_apache24 * rext ;
11573+ rext = (cve_2013_5704_apache24 * )& r -> useragent_addr ;
11574+ #endif
11575+
11576+ rext -> fields .trailers_in = apr_table_make (r -> pool , 5 );
11577+ rext -> fields .trailers_out = apr_table_make (r -> pool , 5 );
11578+ }
11579+ else {
11580+ /*
11581+ * Finally, to allow forward portability of a compiled mod_wsgi
11582+ * binary from an Apache version without the CVE-2013-5704
11583+ * change to one where it is, without needing to recompile
11584+ * mod_wsgi, we set fields in the extra memory we added before
11585+ * the actual request_rec.
11586+ */
11587+
11588+ cve_2013_5704_fields * rext ;
11589+ rext = (cve_2013_5704_fields * )(r + 1 );
11590+
11591+ rext -> trailers_in = apr_table_make (r -> pool , 5 );
11592+ rext -> trailers_out = apr_table_make (r -> pool , 5 );
11593+ }
11594+ #endif
11595+
1148011596 r -> per_dir_config = r -> server -> lookup_defaults ;
1148111597
1148211598 r -> sent_bodyct = 0 ;
0 commit comments