[pkg-lighttpd] r583 - in lighttpd/trunk: debian debian/patches src

Arno Töll atoell-guest at alioth.debian.org
Wed Nov 21 13:43:22 UTC 2012


Author: atoell-guest
Date: 2012-11-21 13:43:22 +0000 (Wed, 21 Nov 2012)
New Revision: 583

Added:
   lighttpd/trunk/debian/patches/connection-dos.patch
   lighttpd/trunk/debian/patches/series
Modified:
   lighttpd/trunk/debian/changelog
   lighttpd/trunk/debian/rules
   lighttpd/trunk/src/request.c
Log:
Apply DoS fix patch

Modified: lighttpd/trunk/debian/changelog
===================================================================
--- lighttpd/trunk/debian/changelog	2012-11-18 13:02:29 UTC (rev 582)
+++ lighttpd/trunk/debian/changelog	2012-11-21 13:43:22 UTC (rev 583)
@@ -1,11 +1,12 @@
-lighttpd (1.4.31-2) UNRELEASED; urgency=low
+lighttpd (1.4.31-3) unstable; urgency=high
 
-  * NOT RELEASED YET
   * Fix "configuration files refer to wrong path for documentation"
     by merging a patch supplied by  Denis Laxalde <denis at laxalde.org>
-     (Closes: #676641)
+    (Closes: #676641)
+  * CVE-2012-5533: Fix Denial Of Service attacks against Lighttpd by sending faulty
+    Connection headers
 
- -- Arno Töll <arno at debian.org>  Wed, 13 Jun 2012 01:28:28 +0200
+ -- Arno Töll <arno at debian.org>  Wed, 21 Nov 2012 14:42:32 +0100
 
 lighttpd (1.4.31-1) unstable; urgency=low
 

Added: lighttpd/trunk/debian/patches/connection-dos.patch
===================================================================
--- lighttpd/trunk/debian/patches/connection-dos.patch	                        (rev 0)
+++ lighttpd/trunk/debian/patches/connection-dos.patch	2012-11-21 13:43:22 UTC (rev 583)
@@ -0,0 +1,112 @@
+From: Stefan Bühler <stbuehler at web.de>
+Subject: Fix DoS in header value split (CVE-2012-5533)
+
+Fix DoS in header value split (reported by Jesse Sipprell; CVE-2012-5533=
+
+Any client which is able to connect to lighttpd can cause a DoS by sending
+"strange" Connection headers, for example: "Connection: TE,,Keep-Alive". This
+patch fixes the issue.
+--- a/src/request.c
++++ b/src/request.c
+@@ -209,9 +209,11 @@
+ #endif
+ 
+ static int http_request_split_value(array *vals, buffer *b) {
+-	char *s;
+ 	size_t i;
+ 	int state = 0;
++
++	const char *current;
++	const char *token_start = NULL, *token_end = NULL;
+ 	/*
+ 	 * parse
+ 	 *
+@@ -222,53 +224,52 @@
+ 
+ 	if (b->used == 0) return 0;
+ 
+-	s = b->ptr;
+-
+-	for (i =0; i < b->used - 1; ) {
+-		char *start = NULL, *end = NULL;
++	current = b->ptr;
++	for (i =  0; i < b->used; ++i, ++current) {
+ 		data_string *ds;
+ 
+ 		switch (state) {
+-		case 0: /* ws */
+-
+-			/* skip ws */
+-			for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++);
+-
+-
+-			state = 1;
+-			break;
+-		case 1: /* value */
+-			start = s;
+-
+-			for (; *s != ',' && i < b->used - 1; i++, s++);
+-			if (start == s) break; /* empty fields are skipped */
+-			end = s - 1;
+-
+-			for (; end > start && (*end == ' ' || *end == '\t'); end--);
+-			if (start == end) break; /* empty fields are skipped */
+-
+-			if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
+-				ds = data_string_init();
++		case 0: /* find start of a token */
++			switch (*current) {
++			case ' ':
++			case '\t': /* skip white space */
++			case ',': /* skip empty token */
++				break;
++			case '\0': /* end of string */
++				return 0;
++			default:
++				/* found real data, switch to state 1 to find the end of the token */
++				token_start = token_end = current;
++				state = 1;
++				break;
+ 			}
++			break;
++		case 1: /* find end of token and last non white space character */
++			switch (*current) {
++			case ' ':
++			case '\t':
++				/* space - don't update token_end */
++				break;
++			case ',':
++			case '\0': /* end of string also marks the end of a token */
++				if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
++					ds = data_string_init();
++				}
+ 
+-			buffer_copy_string_len(ds->value, start, end-start+1);
+-			array_insert_unique(vals, (data_unset *)ds);
++				buffer_copy_string_len(ds->value, token_start, token_end-token_start+1);
++				array_insert_unique(vals, (data_unset *)ds);
+ 
+-			if (*s == ',') {
+ 				state = 0;
+-				i++;
+-				s++;
+-			} else {
+-				/* end of string */
+-
+-				state = 2;
++				break;
++			default:
++				/* no white space, update token_end to include current character */
++				token_end = current;
++				break;
+ 			}
+ 			break;
+-		default:
+-			i++;
+-			break;
+ 		}
+ 	}
++
+ 	return 0;
+ }
+ 

Added: lighttpd/trunk/debian/patches/series
===================================================================
--- lighttpd/trunk/debian/patches/series	                        (rev 0)
+++ lighttpd/trunk/debian/patches/series	2012-11-21 13:43:22 UTC (rev 583)
@@ -0,0 +1 @@
+connection-dos.patch

Modified: lighttpd/trunk/debian/rules
===================================================================
--- lighttpd/trunk/debian/rules	2012-11-18 13:02:29 UTC (rev 582)
+++ lighttpd/trunk/debian/rules	2012-11-21 13:43:22 UTC (rev 583)
@@ -19,7 +19,8 @@
                 --with-openssl \
                 --with-pcre \
                 --with-webdav-locks \
-                --with-webdav-props
+		--with-webdav-props \
+		$(shell dpkg-buildflags --export=configure)
 
 override_dh_fixperms:
 	dh_fixperms

Modified: lighttpd/trunk/src/request.c
===================================================================
--- lighttpd/trunk/src/request.c	2012-11-18 13:02:29 UTC (rev 582)
+++ lighttpd/trunk/src/request.c	2012-11-21 13:43:22 UTC (rev 583)
@@ -209,9 +209,11 @@
 #endif
 
 static int http_request_split_value(array *vals, buffer *b) {
-	char *s;
 	size_t i;
 	int state = 0;
+
+	const char *current;
+	const char *token_start = NULL, *token_end = NULL;
 	/*
 	 * parse
 	 *
@@ -222,53 +224,52 @@
 
 	if (b->used == 0) return 0;
 
-	s = b->ptr;
-
-	for (i =0; i < b->used - 1; ) {
-		char *start = NULL, *end = NULL;
+	current = b->ptr;
+	for (i =  0; i < b->used; ++i, ++current) {
 		data_string *ds;
 
 		switch (state) {
-		case 0: /* ws */
-
-			/* skip ws */
-			for (; (*s == ' ' || *s == '\t') && i < b->used - 1; i++, s++);
-
-
-			state = 1;
+		case 0: /* find start of a token */
+			switch (*current) {
+			case ' ':
+			case '\t': /* skip white space */
+			case ',': /* skip empty token */
+				break;
+			case '\0': /* end of string */
+				return 0;
+			default:
+				/* found real data, switch to state 1 to find the end of the token */
+				token_start = token_end = current;
+				state = 1;
+				break;
+			}
 			break;
-		case 1: /* value */
-			start = s;
+		case 1: /* find end of token and last non white space character */
+			switch (*current) {
+			case ' ':
+			case '\t':
+				/* space - don't update token_end */
+				break;
+			case ',':
+			case '\0': /* end of string also marks the end of a token */
+				if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
+					ds = data_string_init();
+				}
 
-			for (; *s != ',' && i < b->used - 1; i++, s++);
-			if (start == s) break; /* empty fields are skipped */
-			end = s - 1;
+				buffer_copy_string_len(ds->value, token_start, token_end-token_start+1);
+				array_insert_unique(vals, (data_unset *)ds);
 
-			for (; end > start && (*end == ' ' || *end == '\t'); end--);
-			if (start == end) break; /* empty fields are skipped */
-
-			if (NULL == (ds = (data_string *)array_get_unused_element(vals, TYPE_STRING))) {
-				ds = data_string_init();
-			}
-
-			buffer_copy_string_len(ds->value, start, end-start+1);
-			array_insert_unique(vals, (data_unset *)ds);
-
-			if (*s == ',') {
 				state = 0;
-				i++;
-				s++;
-			} else {
-				/* end of string */
-
-				state = 2;
+				break;
+			default:
+				/* no white space, update token_end to include current character */
+				token_end = current;
+				break;
 			}
 			break;
-		default:
-			i++;
-			break;
 		}
 	}
+
 	return 0;
 }
 




More information about the pkg-lighttpd-maintainers mailing list