[pkg-lighttpd] Bug#857255: lighttpd: mod_scgi: out of bounds read in scgi_demux_response

Stefan Bühler source at stbuehler.de
Thu Mar 9 10:08:36 UTC 2017


Hi Helmut,

On 03/09/2017 10:06 AM, Helmut Grohne wrote:
> Package: lighttpd
> Version: 1.4.45-1
> Tags: security patch
> 
> While debugging a problem with lighttpd on behalf of my current employer
> Intenta GmbH, I found an out of bounds read.
> 
> http://sources.debian.net/src/lighttpd/1.4.45-1/src/mod_scgi.c/#L1828
> | 			for (c = hctx->response_header->ptr, cp = 0, used = buffer_string_length(hctx->response_header); used; c++, cp++, used--) {
> | 				if (*c == ':') in_header = 1;
> | 				else if (*c == '\n') {
> | 					if (in_header == 0) {
> | 						/* got a response without a response header */
> |
> | 						c = NULL;
> | 						header_end = 1;
> | 						break;
> | 					}
> |
> | 					if (eol == EOL_UNSET) eol = EOL_N;
> |
> | 					if (*(c+1) == '\n') {
> | 						header_end = 1;
> | 						hlen = cp + 2;
> | 						break;
> | 					}
> |
> | 				} else if (used > 1 && *c == '\r' && *(c+1) == '\n') {
> 
> The loop is constructed such that up to `used` bytes can be read
> starting from `c`. Thus the access to `*c` is ok. However accessing
> `*(c+1)` may be out of bounds. The condition should check for `used > 1`
> before accessing `*(c+1)`. Both the later condition checking for CR LF
> in the excerpt above and an even later condition checking for double CR
> LF do check for sufficient buffer contents. It's only this one
> occurrence that misses the check. In practise, this can result in
> lighttpd sending corrupted responses to its clients when its SCGI reads
> are chunked in a bad way (i.e. they end with '\n').

Since a buffer-API-refactoring some time ago all buffers should be
NUL-terminated.  I.e. if `*c == '\n'` is true `c` must not point to the
last character of the buffer.

If you have reason to believe otherwise please let us know :)

If you managed to trigger this in some older version we'd be interested
to know about it too - some dists are using pretty old versions.

> The following patch fixes the problem:
> --- a/src/mod_scgi.c
> +++ b/src/mod_scgi.c
> @@ -1826,7 +1826,7 @@
> 
>  					if (eol == EOL_UNSET) eol = EOL_N;
> 
> -					if (*(c+1) == '\n') {
> +					if (used > 1 && *(c+1) == '\n') {
>  						header_end = 1;
>  						hlen = cp + 2;
>  						break;

Patch looks fine though.

- Stefan



More information about the pkg-lighttpd-maintainers mailing list