@@ -11372,6 +11372,27 @@ static apr_status_t wsgi_header_filter(ap_filter_t *f, apr_bucket_brigade *b)
1137211372 return ap_pass_brigade (f -> next , b );
1137311373}
1137411374
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+
1137511396static int wsgi_hook_daemon_handler (conn_rec * c )
1137611397{
1137711398 apr_socket_t * csd ;
@@ -11401,6 +11422,13 @@ static int wsgi_hook_daemon_handler(conn_rec *c)
1140111422
1140211423 int queue_timeout_occurred = 0 ;
1140311424
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+
1140411432 /* Don't do anything if not in daemon process. */
1140511433
1140611434 if (!wsgi_daemon_pool )
@@ -11454,10 +11482,22 @@ static int wsgi_hook_daemon_handler(conn_rec *c)
1145411482 next = current -> next ;
1145511483 }
1145611484
11457- /* 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+ */
1145811497
1145911498 apr_pool_create (& p , c -> pool );
11460- r = apr_pcalloc (p , sizeof (request_rec ));
11499+
11500+ r = apr_pcalloc (p , sizeof (request_rec )+ sizeof (cve_2013_5704_fields ));
1146111501
1146211502 r -> pool = p ;
1146311503 r -> connection = c ;
@@ -11481,24 +11521,76 @@ static int wsgi_hook_daemon_handler(conn_rec *c)
1148111521 r -> proto_input_filters = c -> input_filters ;
1148211522 r -> input_filters = r -> proto_input_filters ;
1148311523
11484- #if ( AP_SERVER_MINORVERSION_NUMBER <= 2 && \
11485- AP_MODULE_MAGIC_AT_LEAST ( 20051115 , 36 )) || \
11486- ( AP_SERVER_MINORVERSION_NUMBER > 2 && \
11487- AP_MODULE_MAGIC_AT_LEAST (20120211 , 37 ))
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 ))
1148811528
1148911529 /*
1149011530 * New request_rec fields were added to Apache because of changes
1149111531 * related to CVE-2013-5704. The change means that mod_wsgi version
1149211532 * 4.4.0-4.4.5 will crash if run on the Apache versions with the
11493- * addition fields if mod_wsgi daemon mode is used. If the change
11494- * for the CVE was backported, even 4.4.6 onwards will crash as
11495- * Apache with backported changes will not update the module magic
11496- * number. In that case the cpp conditional here would have to be
11497- * removed from around the code.
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.
1149811536 */
1149911537
1150011538 r -> trailers_in = apr_table_make (r -> pool , 5 );
1150111539 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+ }
1150211594#endif
1150311595
1150411596 r -> per_dir_config = r -> server -> lookup_defaults ;
0 commit comments