From 864e8256ec767826964f0c8b27d468a1ea1ed9aa Mon Sep 17 00:00:00 2001 From: Willy Tarreau Date: Mon, 28 Dec 2009 17:36:37 +0100 Subject: [PATCH] [BUG] stream_sock: wrong max computation on recv Since the introduction of the automatic sizing of buffers during reads, a bug appeared where the max size could be negative, causing large chunks of memory to be overwritten during recv() calls if a read pointer was already past the buffer's limit. --- src/stream_sock.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/src/stream_sock.c b/src/stream_sock.c index e75bdafe8..a733e9939 100644 --- a/src/stream_sock.c +++ b/src/stream_sock.c @@ -296,28 +296,27 @@ int stream_sock_read(int fd) { #endif cur_read = 0; while (1) { + max = buffer_max_len(b) - b->l; + + if (max <= 0) { + b->flags |= BF_FULL; + si->flags |= SI_FL_WAIT_ROOM; + break; + } + /* * 1. compute the maximum block size we can read at once. */ if (b->l == 0) { /* let's realign the buffer to optimize I/O */ b->r = b->w = b->lr = b->data; - max = buffer_max_len(b); } else if (b->r > b->w) { - max = b->data + buffer_max_len(b) - b->r; - } - else { - max = b->w - b->r; - if (max > buffer_max_len(b)) - max = buffer_max_len(b); - } - - if (max == 0) { - b->flags |= BF_FULL; - si->flags |= SI_FL_WAIT_ROOM; - break; + /* remaining space wraps at the end, with a moving limit */ + if (max > b->data + b->size - b->r) + max = b->data + b->size - b->r; } + /* else max is already OK */ /* * 2. read the largest possible block