Project

General

Profile

Bug #2670

connection hangs when final cr/lf is in seperate packet

Added by mikevs over 3 years ago. Updated over 3 years ago.

Status:
Fixed
Priority:
High
Assignee:
-
Category:
core
Target version:
Start date:
2015-09-23
Due date:
% Done:

100%

Estimated time:
Missing in 1.5.x:

Description

Starting from version 1.4.36, if you send a request without a body (GET, OPTIONS) and the headers and the final crlf are in different TCP packets, the connection hangs.

(I discovered this because I was using Apache as a reverse proxy in front of lighttpd and it behaves this way - at least with OPTIONS).

This does not happen if the size of the headers is smaller than approximately 64 bytes.

To reproduce:

telnet to a lighttpd server. Cut and paste the following data (WITHOUT an empty line at the end):

GET / HTTP/1.1
Host: localhost
X-Filler: 0123456789012345678901234567890

Now wait a short while and send the final CRLF (by pressing enter).

Expected result: HTTP reply
Actual result: connection hangs

This works on 1.4.35, and is broken on 1.4.36 and 1.4.37.

Reproduced on FreeBSD 10 and Ubuntu 15.04.

Configuration file used:

# Minimal lighttpd.conf
var.log_root    = "/tmp" 
var.server_root = "/tmp" 
var.state_dir   = "/tmp" 
var.home_dir    = "/tmp" 
var.conf_dir    = "/tmp" 

server.port = 1337
server.document-root = "/tmp" 


Related issues

Has duplicate Bug #2686: Bug in read parsing codeDuplicate2015-12-01

Actions
Has duplicate Bug #2683: HTTP requests with long GET are getting droppedDuplicate2015-11-20

Actions

Associated revisions

Revision 3043 (diff)
Added by stbuehler over 3 years ago

[core] fix search for header end if split across chunks (fixes #2670)

From: Stefan Bühler <>

Revision a93be994 (diff)
Added by stbuehler over 3 years ago

[core] fix search for header end if split across chunks (fixes #2670)

From: Stefan Bühler <>

git-svn-id: svn://svn.lighttpd.net/lighttpd/branches/lighttpd-1.4.x@3043 152afb58-edef-0310-8abb-c4023f1b3aa9

History

#1

Updated by stbuehler over 3 years ago

  • Priority changed from Normal to High

Good catch - thanks for reporting.

#2

Updated by stbuehler over 3 years ago

The bug is old (in connections.c connection_handle_read_state()), but recent changes made it occur more often; the following patch fixes that.

Right now the bug triggers at the 64-byte boundary, the patch should make it occur somewhere at 4k or more.

diff --git a/src/connections.c b/src/connections.c
index 7e205af..46e46b1 100644
--- a/src/connections.c
+++ b/src/connections.c
@@ -336,10 +336,11 @@ static int connection_handle_read(server *srv, connection *con) {
     len = recv(con->fd, mem, mem_len, 0);
 #else /* __WIN32 */
     if (ioctl(con->fd, FIONREAD, &toread) || toread == 0 || toread <= 4*1024) {
-        if (toread > MAX_READ_LIMIT) toread = MAX_READ_LIMIT;
-    } else {
         toread = 4096;
     }
+    else if (toread > MAX_READ_LIMIT) {
+        toread = MAX_READ_LIMIT;
+    }
     chunkqueue_get_memory(con->read_queue, &mem, &mem_len, 0, toread);

     len = read(con->fd, mem, mem_len);
#3

Updated by stbuehler over 3 years ago

r2979 introduced the bug; the local code looks like it could end up triggering an out-of-bounds read, but I couldn't find a way to trigger it; I think the allocation pattern prevents it: we only search for at most 3 bytes in the next buffer, and the previous buffer would have to be smaller than that, in which case we would have reused the previous buffer for the following data.

#4

Updated by stbuehler over 3 years ago

  • Status changed from New to Fixed
  • % Done changed from 0 to 100

Applied in changeset r3043.

#5

Updated by stbuehler over 3 years ago

  • Has duplicate Bug #2686: Bug in read parsing code added
#6

Updated by stbuehler over 3 years ago

  • Has duplicate Bug #2683: HTTP requests with long GET are getting dropped added

Also available in: Atom