File httpd-2.2.x-bnc788121-CVE-2012-4557-mod_proxy_ajp_timeout.diff of Package apache2
diff -rNU 20 ../httpd-2.2.12-o/modules/proxy/ajp_link.c ./modules/proxy/ajp_link.c
--- ../httpd-2.2.12-o/modules/proxy/ajp_link.c 2006-07-12 05:38:44.000000000 +0200
+++ ./modules/proxy/ajp_link.c 2013-01-22 14:17:44.000000000 +0100
@@ -78,41 +78,41 @@
apr_status_t ajp_ilink_receive(apr_socket_t *sock, ajp_msg_t *msg)
{
apr_status_t status;
apr_size_t hlen;
apr_size_t blen;
if (sock == NULL) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"ajp_ilink_receive(): NULL socket provided");
return AJP_EINVAL;
}
hlen = msg->header_len;
status = ilink_read(sock, msg->buf, hlen);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL,
"ajp_ilink_receive() can't receive header");
- return AJP_ENO_HEADER;
+ return (APR_STATUS_IS_TIMEUP(status) ? APR_TIMEUP : AJP_ENO_HEADER);
}
status = ajp_msg_check_header(msg, &blen);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
"ajp_ilink_receive() received bad header");
return AJP_EBAD_HEADER;
}
status = ilink_read(sock, msg->buf + hlen, blen);
if (status != APR_SUCCESS) {
ap_log_error(APLOG_MARK, APLOG_ERR, status, NULL,
"ajp_ilink_receive() error while receiving message body "
"of length %" APR_SIZE_T_FMT,
hlen);
return AJP_EBAD_MESSAGE;
}
diff -rNU 20 ../httpd-2.2.12-o/modules/proxy/mod_proxy_ajp.c ./modules/proxy/mod_proxy_ajp.c
--- ../httpd-2.2.12-o/modules/proxy/mod_proxy_ajp.c 2013-01-22 14:14:56.000000000 +0100
+++ ./modules/proxy/mod_proxy_ajp.c 2013-01-22 14:18:42.000000000 +0100
@@ -319,41 +319,52 @@
* for later resusage by the next request again.
* Close it to clean things up.
*/
conn->close++;
return HTTP_BAD_REQUEST;
}
}
/* read the response */
conn->data = NULL;
status = ajp_read_header(conn->sock, r, maxsize,
(ajp_msg_t **)&(conn->data));
if (status != APR_SUCCESS) {
/* We had a failure: Close connection to backend */
conn->close++;
apr_brigade_destroy(input_brigade);
ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server,
"proxy: read response failed from %pI (%s)",
conn->worker->cp->addr,
conn->worker->hostname);
- /*
+
+
+ /* If we had a successful cping/cpong and then a timeout
+ * we assume it is a request that cause a back-end timeout,
+ * but doesn't affect the whole worker.
+ */
+ if (APR_STATUS_IS_TIMEUP(status) && conn->worker->ping_timeout_set) {
+ return HTTP_GATEWAY_TIME_OUT;
+ }
+
+/* http://svn.apache.org/viewvc?view=revision&revision=1227298 :
+
* This is only non fatal when we have not sent (parts) of a possible
* request body so far (we do not store it and thus cannot sent it
* again) and the method is idempotent. In this case we can dare to
* retry it with a different worker if we are a balancer member.
*/
if (!send_body && (is_idempotent(r) == METHOD_IDEMPOTENT)) {
return HTTP_SERVICE_UNAVAILABLE;
}
return HTTP_INTERNAL_SERVER_ERROR;
}
/* parse the reponse */
result = ajp_parse_type(r, conn->data);
output_brigade = apr_brigade_create(p, r->connection->bucket_alloc);
/*
* Prepare apr_pollfd_t struct for possible later check if there is currently
* data available from the backend (do not flush response to client)
* or not (flush response to client)
*/
conn_poll = apr_pcalloc(p, sizeof(apr_pollfd_t));