File httpd-2.2.x-bnc743743-CVE-2012-0053-server_protocol_c-cookie_exposure.diff of Package apache2.1524

diff -rNU 30 ../httpd-2.2.21-o/server/protocol.c ./server/protocol.c
--- ../httpd-2.2.21-o/server/protocol.c	2012-02-14 02:20:09.000000000 +0100
+++ ./server/protocol.c	2012-02-14 02:26:15.000000000 +0100
@@ -667,170 +667,192 @@
     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;
 }
 
+/* get the length of the field name for logging, but no more than 80 bytes */
+#define LOG_NAME_MAX_LEN 80
+static int field_name_len(const char *field)
+{
+    const char *end = ap_strchr_c(field, ':');
+    if (end == NULL || end - field > LOG_NAME_MAX_LEN)
+        return LOG_NAME_MAX_LEN;
+    return end - field;
+}
+
+
 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;
         rv = ap_rgetline(&field, r->server->limit_req_fieldsize + 2,
                          &len, r, 0, bb);
 
         if (rv != APR_SUCCESS) {
             if (APR_STATUS_IS_TIMEUP(rv)) {
                 r->status = HTTP_REQUEST_TIME_OUT;
             }
             else {
                 r->status = HTTP_BAD_REQUEST;
             }
 
             /* 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 field size.
              */
             if (rv == APR_ENOSPC && field) {
                 /* insure ap_escape_html will terminate correctly */
                 field[len - 1] = '\0';
                 apr_table_setn(r->notes, "error-notes",
-                               apr_pstrcat(r->pool,
+                               apr_psprintf(r->pool,
                                            "Size of a request header field "
                                            "exceeds server limit.<br />\n"
-                                           "<pre>\n",
-                                           ap_escape_html(r->pool, field),
-                                           "</pre>\n", NULL));
+					   "<pre>\n%.*s\n</pre>/n",
+					   field_name_len(field),
+					   ap_escape_html(r->pool, field)));
+		ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+			"Request header exceeds LimitRequestFieldSize: "
+			"%.*s", field_name_len(field), field);
             }
             return;
         }
 
         if (last_field != NULL) {
             if ((len > 0) && ((*field == '\t') || *field == ' ')) {
                 /* This line is a continuation of the preceding line(s),
                  * so append it to the line that we've set aside.
                  * Note: this uses a power-of-two allocator to avoid
                  * doing O(n) allocs and using O(n^2) space for
                  * continuations that span many many lines.
                  */
                 apr_size_t fold_len = last_len + len + 1; /* trailing null */
 
                 if (fold_len >= (apr_size_t)(r->server->limit_req_fieldsize)) {
                     r->status = HTTP_BAD_REQUEST;
                     /* report what we have accumulated so far before the
                      * overflow (last_field) as the field with the problem
                      */
                     apr_table_setn(r->notes, "error-notes",
-                                   apr_pstrcat(r->pool,
+                                   apr_psprintf(r->pool,
                                                "Size of a request header field "
                                                "after folding "
                                                "exceeds server limit.<br />\n"
-                                               "<pre>\n",
-                                               ap_escape_html(r->pool, last_field),
-                                               "</pre>\n", NULL));
+					       "<pre>\n%.*s\n</pre>\n",
+					       field_name_len(last_field),
+					       ap_escape_html(r->pool, last_field)));
+		    ap_log_rerror(APLOG_MARK, APLOG_INFO, 0, r,
+				"Request header exceeds LimitRequestFieldSize "
+				"after folding: %.*s",
+				field_name_len(last_field), last_field);
                     return;
                 }
 
                 if (fold_len > alloc_len) {
                     char *fold_buf;
                     alloc_len += alloc_len;
                     if (fold_len > alloc_len) {
                         alloc_len = fold_len;
                     }
                     fold_buf = (char *)apr_palloc(r->pool, alloc_len);
                     memcpy(fold_buf, last_field, last_len);
                     last_field = fold_buf;
                 }
                 memcpy(last_field + last_len, field, len +1); /* +1 for nul */
                 last_len += len;
                 folded = 1;
             }
             else /* not a continuation line */ {
 
                 if (r->server->limit_req_fields
                     && (++fields_read > r->server->limit_req_fields)) {
                     r->status = HTTP_BAD_REQUEST;
                     apr_table_setn(r->notes, "error-notes",
                                    "The number of request header fields "
                                    "exceeds this server's limit.");
                     return;
                 }
 
                 if (!(value = strchr(last_field, ':'))) { /* Find ':' or    */
                     r->status = HTTP_BAD_REQUEST;      /* abort bad request */
                     apr_table_setn(r->notes, "error-notes",
-                                   apr_pstrcat(r->pool,
+                                   apr_psprintf(r->pool,
                                                "Request header field is "
                                                "missing ':' separator.<br />\n"
-                                               "<pre>\n",
+					       "<pre>\n%.*s</pre>\n",
+					       (int)LOG_NAME_MAX_LEN,
                                                ap_escape_html(r->pool,
-                                                              last_field),
-                                               "</pre>\n", NULL));
+						  last_field)));
+		    ap_log_rerror(APLOG_MARK, APLOG_DEBUG, 0, r,
+				"Request header field is missing ':' "
+				"separator: %.*s", (int)LOG_NAME_MAX_LEN,
+				last_field);
                     return;
                 }
 
                 tmp_field = value - 1; /* last character of field-name */
 
                 *value++ = '\0'; /* NUL-terminate at colon */
 
                 while (*value == ' ' || *value == '\t') {
                     ++value;            /* Skip to start of value   */
                 }
 
                 /* Strip LWS after field-name: */
                 while (tmp_field > last_field
                        && (*tmp_field == ' ' || *tmp_field == '\t')) {
                     *tmp_field-- = '\0';
                 }
 
                 /* Strip LWS after field-value: */
                 tmp_field = last_field + last_len - 1;
                 while (tmp_field > value
                        && (*tmp_field == ' ' || *tmp_field == '\t')) {
                     *tmp_field-- = '\0';
                 }
 
                 apr_table_addn(r->headers_in, last_field, value);
 
                 /* reset the alloc_len so that we'll allocate a new
                  * buffer if we have to do any more folding: we can't
                  * use the previous buffer because its contents are
                  * now part of r->headers_in
openSUSE Build Service is sponsored by