]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
[BUG] stream_sock: wrong max computation on recv
authorWilly Tarreau <w@1wt.eu>
Mon, 28 Dec 2009 16:36:37 +0000 (17:36 +0100)
committerWilly Tarreau <w@1wt.eu>
Mon, 28 Dec 2009 16:36:37 +0000 (17:36 +0100)
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

index e75bdafe836ce6401049817afce7bc656907e0e6..a733e9939ca9b24df3c560861754fa796127411d 100644 (file)
@@ -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