Hello community, here is the log from the commit of package apache2 for openSUSE:11.3 checked in at Wed Oct 26 19:12:55 CEST 2011. -------- --- old-versions/11.3/UPDATES/all/apache2/apache2.changes 2011-08-31 18:39:19.000000000 +0200 +++ 11.3/apache2/apache2.changes 2011-10-26 15:52:56.000000000 +0200 @@ -1,0 +2,33 @@ +Mon Oct 24 23:42:10 CEST 2011 - draht@suse.de + +- httpd-2.2.x-CVE-2011-3348-mod_proxy_ajp.patch fixes DoS as + described in CVE-2011-3348: unrecognized http method. [bnc#719236] +- httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff fixes mod_proxy + reverse exposure via RewriteRule or ProxyPassMatch directives. + This is CVE-2011-3368 via [bnc#722545], and second iteration after + consulting with Ruediger Pluem. + +------------------------------------------------------------------- +Mon Sep 19 02:50:43 CEST 2011 - draht@suse.de + +- refinement of httpd-2.2.x-bnc713966-CVE-2011-3192.patch: remove + hard-coded limit of 512 and set the default to 200 as in upstream. + Introduce new config option: Allow MaxRanges + Number of ranges requested, if exceeded, the complete content + is served. + default: 200 + 0|unlimited: unlimited + none: Range headers are ignored. + This option is a backport from 2.2.21. + +------------------------------------------------------------------- +Wed Sep 14 00:55:49 CEST 2011 - draht@suse.de + +- re-worked httpd-2.2.x-bnc713966-CVE-2011-3192.patch for a + regression in previous fix that was addressed in 2.2.21. + The maximum number of byte ranges is now hardcoded to 512. + This should be sufficient for most cases, and still a good + limit to prevent a large memory footprint. Requests beyond + 512 ranges are handled with the complete content. + +------------------------------------------------------------------- calling whatdependson for 11.3-i586 New: ---- httpd-2.2.x-CVE-2011-3348-mod_proxy_ajp.patch httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apache2.spec ++++++ --- /var/tmp/diff_new_pack.GcjEYg/_old 2011-10-26 19:11:13.000000000 +0200 +++ /var/tmp/diff_new_pack.GcjEYg/_new 2011-10-26 19:11:13.000000000 +0200 @@ -64,7 +64,7 @@ Group: Productivity/Networking/Web/Servers %define realver 2.2.15 Version: 2.2.15 -Release: 4.<RELEASE5> +Release: 4.<RELEASE7> #Source0: http://www.apache.org/dist/httpd-%{version}.tar.bz2 Source0: http://httpd.apache.org/dev/dist/httpd-%{realver}.tar.bz2 # Add file to take mtime from it in prep section @@ -125,6 +125,8 @@ Patch102: httpd-2.2.x-bnc627030-CVE-2010-1452.patch Patch103: httpd-2.2.x-bnc690734.patch Patch104: httpd-2.2.x-bnc713966-CVE-2011-3192.patch +Patch105: httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff +Patch106: httpd-2.2.x-CVE-2011-3348-mod_proxy_ajp.patch Url: http://httpd.apache.org/ Icon: Apache.xpm Summary: The Apache Web Server Version 2.2 @@ -179,7 +181,7 @@ Apache distribution. See /usr/share/doc/packages/apache2/, http://httpd.apache.org/, and -http://httpd.apache.org/docs-2.0/upgrading.html. +http://httpd.apache.org/docs-2.2/upgrading.html. @@ -304,7 +306,7 @@ %package devel License: ASLv.. -Summary: Apache 2.0 Header and Include Files +Summary: Apache 2.2 Header and Include Files Group: Development/Libraries/C and C++ Requires: %{name} = %{version} %{pname}-MPM Requires: libapr1-devel libapr-util1-devel @@ -401,6 +403,8 @@ %patch102 -p1 %patch103 -p0 %patch104 -p0 +%patch105 -p0 +%patch106 -p0 # cat $RPM_SOURCE_DIR/SUSE-NOTICE >> NOTICE # ++++++ httpd-2.2.x-CVE-2011-3348-mod_proxy_ajp.patch ++++++ diff -rNU 50 ../httpd-2.2.17-o/modules/proxy/mod_proxy_ajp.c ./modules/proxy/mod_proxy_ajp.c --- ../httpd-2.2.17-o/modules/proxy/mod_proxy_ajp.c 2010-08-25 16:16:25.000000000 +0200 +++ ./modules/proxy/mod_proxy_ajp.c 2011-10-24 23:37:12.000000000 +0200 @@ -166,101 +166,103 @@ { apr_status_t status; int result; apr_bucket *e; apr_bucket_brigade *input_brigade; apr_bucket_brigade *output_brigade; ajp_msg_t *msg; apr_size_t bufsiz = 0; char *buff; char *send_body_chunk_buff; apr_uint16_t size; const char *tenc; int havebody = 1; int output_failed = 0; int backend_failed = 0; apr_off_t bb_len; int data_sent = 0; int request_ended = 0; int headers_sent = 0; int rv = 0; apr_int32_t conn_poll_fd; apr_pollfd_t *conn_poll; proxy_server_conf *psf = ap_get_module_config(r->server->module_config, &proxy_module); apr_size_t maxsize = AJP_MSG_BUFFER_SZ; int send_body = 0; apr_off_t content_length = 0; if (psf->io_buffer_size_set) maxsize = psf->io_buffer_size; if (maxsize > AJP_MAX_BUFFER_SZ) maxsize = AJP_MAX_BUFFER_SZ; else if (maxsize < AJP_MSG_BUFFER_SZ) maxsize = AJP_MSG_BUFFER_SZ; maxsize = APR_ALIGN(maxsize, 1024); /* * Send the AJP request to the remote server */ /* send request headers */ status = ajp_send_header(conn->sock, r, maxsize, uri); if (status != APR_SUCCESS) { conn->close++; ap_log_error(APLOG_MARK, APLOG_ERR, status, r->server, "proxy: AJP: request failed to %pI (%s)", conn->worker->cp->addr, conn->worker->hostname); if (status == AJP_EOVERFLOW) return HTTP_BAD_REQUEST; - else { + else if (status == AJP_EBAD_METHOD) { + return HTTP_NOT_IMPLEMENTED; + } else { /* * This is only non fatal when the method is idempotent. In this * case we can dare to retry it with a different worker if we are * a balancer member. */ if (is_idempotent(r) == METHOD_IDEMPOTENT) { return HTTP_SERVICE_UNAVAILABLE; } return HTTP_INTERNAL_SERVER_ERROR; } } /* allocate an AJP message to store the data of the buckets */ bufsiz = maxsize; status = ajp_alloc_data_msg(r->pool, &buff, &bufsiz, &msg); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ conn->close++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: ajp_alloc_data_msg failed"); return HTTP_INTERNAL_SERVER_ERROR; } /* read the first bloc of data */ input_brigade = apr_brigade_create(p, r->connection->bucket_alloc); tenc = apr_table_get(r->headers_in, "Transfer-Encoding"); if (tenc && (strcasecmp(tenc, "chunked") == 0)) { /* The AJP protocol does not want body data yet */ ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: request is chunked"); } else { /* Get client provided Content-Length header */ content_length = get_content_length(r); status = ap_get_brigade(r->input_filters, input_brigade, AP_MODE_READBYTES, APR_BLOCK_READ, maxsize - AJP_HEADER_SZ); if (status != APR_SUCCESS) { /* We had a failure: Close connection to backend */ conn->close++; ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: ap_get_brigade failed"); apr_brigade_destroy(input_brigade); return HTTP_BAD_REQUEST; } /* have something */ if (APR_BUCKET_IS_EOS(APR_BRIGADE_LAST(input_brigade))) { ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server, "proxy: APR_BUCKET_IS_EOS"); ++++++ httpd-2.2.x-CVE-2011-3368-server_protocl_c.diff ++++++ diff -rNU 50 ../httpd-2.2.15-o/server/protocol.c ./server/protocol.c --- ../httpd-2.2.15-o/server/protocol.c 2011-10-26 15:50:45.000000000 +0200 +++ ./server/protocol.c 2011-10-26 15:50:54.000000000 +0200 @@ -590,100 +590,125 @@ apr_status_t rv; /* insure ap_rgetline allocates memory each time thru the loop * if there are empty lines */ r->the_request = NULL; rv = ap_rgetline(&(r->the_request), (apr_size_t)(r->server->limit_req_line + 2), &len, r, 0, bb); if (rv != APR_SUCCESS) { r->request_time = apr_time_now(); /* ap_rgetline returns APR_ENOSPC if it fills up the * buffer before finding the end-of-line. This is only going to * happen if it exceeds the configured limit for a request-line. */ if (rv == APR_ENOSPC) { r->status = HTTP_REQUEST_URI_TOO_LARGE; r->proto_num = HTTP_VERSION(1,0); r->protocol = apr_pstrdup(r->pool, "HTTP/1.0"); } return 0; } } while ((len <= 0) && (++num_blank_lines < max_blank_lines)); /* we've probably got something to do, ignore graceful restart requests */ r->request_time = apr_time_now(); ll = r->the_request; r->method = ap_getword_white(r->pool, &ll); #if 0 /* XXX If we want to keep track of the Method, the protocol module should do * it. That support isn't in the scoreboard yet. Hopefully next week * sometime. rbb */ ap_update_connection_status(AP_CHILD_THREAD_FROM_ID(conn->id), "Method", r->method); #endif uri = ap_getword_white(r->pool, &ll); /* Provide quick information about the request method as soon as known */ r->method_number = ap_method_number_of(r->method); if (r->method_number == M_GET && r->method[0] == 'H') { r->header_only = 1; } ap_parse_uri(r, uri); +/* + https://svn.apache.org/viewvc/httpd/httpd/trunk/server/protocol.c?r1=1178566&r2=1179239&pathrev=1179239&view=patch + This is the fix for CVE-2011-3368; via bnc#722545. + */ + + /* RFC 2616: + * Request-URI = "*" | absoluteURI | abs_path | authority + * + * authority is a special case for CONNECT. If the request is not + * using CONNECT, and the parsed URI does not have scheme, and + * it does not begin with '/', and it is not '*', then, fail + * and give a 400 response. */ + if (r->method_number != M_CONNECT + && !r->parsed_uri.scheme + && uri[0] != '/' + && !(uri[0] == '*' && uri[1] == '\0')) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "invalid request-URI %s", uri); + r->args = NULL; + r->hostname = NULL; + r->status = HTTP_BAD_REQUEST; + r->uri = apr_pstrdup(r->pool, uri); + return 0; + } + if (ll[0]) { r->assbackwards = 0; pro = ll; len = strlen(ll); } else { r->assbackwards = 1; pro = "HTTP/0.9"; len = 8; } r->protocol = apr_pstrmemdup(r->pool, pro, len); /* XXX ap_update_connection_status(conn->id, "Protocol", r->protocol); */ /* Avoid sscanf in the common case */ if (len == 8 && pro[0] == 'H' && pro[1] == 'T' && pro[2] == 'T' && pro[3] == 'P' && pro[4] == '/' && apr_isdigit(pro[5]) && pro[6] == '.' && apr_isdigit(pro[7])) { r->proto_num = HTTP_VERSION(pro[5] - '0', pro[7] - '0'); } else if (3 == sscanf(r->protocol, "%4s/%u.%u", http, &major, &minor) && (strcasecmp("http", http) == 0) && (minor < HTTP_VERSION(1, 0)) ) /* don't allow HTTP/0.1000 */ r->proto_num = HTTP_VERSION(major, minor); else r->proto_num = HTTP_VERSION(1, 0); return 1; } AP_DECLARE(void) ap_get_mime_headers_core(request_rec *r, apr_bucket_brigade *bb) { char *last_field = NULL; apr_size_t last_len = 0; apr_size_t alloc_len = 0; char *field; char *value; apr_size_t len; int fields_read = 0; char *tmp_field; /* * Read header lines until we get the empty separator line, a read error, * the connection closes (EOF), reach the server limit, or we timeout. */ while(1) { apr_status_t rv; int folded = 0; field = NULL; @@ -842,103 +867,109 @@ int access_status; apr_bucket_brigade *tmp_bb; apr_socket_t *csd; apr_interval_time_t cur_timeout; apr_pool_create(&p, conn->pool); apr_pool_tag(p, "request"); r = apr_pcalloc(p, sizeof(request_rec)); r->pool = p; r->connection = conn; r->server = conn->base_server; r->user = NULL; r->ap_auth_type = NULL; r->allowed_methods = ap_make_method_list(p, 2); r->headers_in = apr_table_make(r->pool, 25); r->subprocess_env = apr_table_make(r->pool, 25); r->headers_out = apr_table_make(r->pool, 12); r->err_headers_out = apr_table_make(r->pool, 5); r->notes = apr_table_make(r->pool, 5); r->request_config = ap_create_request_config(r->pool); /* Must be set before we run create request hook */ r->proto_output_filters = conn->output_filters; r->output_filters = r->proto_output_filters; r->proto_input_filters = conn->input_filters; r->input_filters = r->proto_input_filters; ap_run_create_request(r); r->per_dir_config = r->server->lookup_defaults; r->sent_bodyct = 0; /* bytect isn't for body */ r->read_length = 0; r->read_body = REQUEST_NO_BODY; r->status = HTTP_REQUEST_TIME_OUT; /* Until we get a request */ r->the_request = NULL; /* Begin by presuming any module can make its own path_info assumptions, * until some module interjects and changes the value. */ r->used_path_info = AP_REQ_DEFAULT_PATH_INFO; tmp_bb = apr_brigade_create(r->pool, r->connection->bucket_alloc); /* Get the request... */ if (!read_request_line(r, tmp_bb)) { - if (r->status == HTTP_REQUEST_URI_TOO_LARGE) { - ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + if (r->status == HTTP_REQUEST_URI_TOO_LARGE + || r->status == HTTP_BAD_REQUEST) { + if (r->status == HTTP_REQUEST_URI_TOO_LARGE) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "request failed: URI too long (longer than %d)", r->server->limit_req_line); + } else if (r->method == NULL) { + ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, + "request failed: invalid characters in URI"); + } ap_send_error_response(r, 0); ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); apr_brigade_destroy(tmp_bb); return r; } apr_brigade_destroy(tmp_bb); return NULL; } /* We may have been in keep_alive_timeout mode, so toggle back * to the normal timeout mode as we fetch the header lines, * as necessary. */ csd = ap_get_module_config(conn->conn_config, &core_module); apr_socket_timeout_get(csd, &cur_timeout); if (cur_timeout != conn->base_server->timeout) { apr_socket_timeout_set(csd, conn->base_server->timeout); cur_timeout = conn->base_server->timeout; } if (!r->assbackwards) { ap_get_mime_headers_core(r, tmp_bb); if (r->status != HTTP_REQUEST_TIME_OUT) { ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r, "request failed: error reading the headers"); ap_send_error_response(r, 0); ap_update_child_status(conn->sbh, SERVER_BUSY_LOG, r); ap_run_log_transaction(r); apr_brigade_destroy(tmp_bb); return r; } if (apr_table_get(r->headers_in, "Transfer-Encoding") && apr_table_get(r->headers_in, "Content-Length")) { /* 2616 section 4.4, point 3: "if both Transfer-Encoding * and Content-Length are received, the latter MUST be * ignored"; so unset it here to prevent any confusion * later. */ apr_table_unset(r->headers_in, "Content-Length"); } } else { if (r->header_only) { /* * Client asked for headers only with HTTP/0.9, which doesn't send * headers! Have to dink things just to make sure the error message * comes through... */ ++++++ httpd-2.2.x-bnc713966-CVE-2011-3192.patch ++++++ ++++ 1343 lines (skipped) ++++ between old-versions/11.3/UPDATES/all/apache2/httpd-2.2.x-bnc713966-CVE-2011-3192.patch ++++ and 11.3/apache2/httpd-2.2.x-bnc713966-CVE-2011-3192.patch continue with "q"... Remember to have fun... -- To unsubscribe, e-mail: opensuse-commit+unsubscribe@opensuse.org For additional commands, e-mail: opensuse-commit+help@opensuse.org