From 63a6288435c35cd628abd530e0dc3bf84168c2e0 Mon Sep 17 00:00:00 2001 From: Markus Armbruster Date: Sun, 27 Dec 2015 15:32:00 +0100 Subject: [PATCH] client: Fix integer wrap around in ring_peek() Peeking beyond either end of the ring buffer must return EOF. We first compute the index, then check whether it's in range. Unfortunately, the index computation r->prod - -n can wrap around while r->prod is still <= RING_SIZE. If it happens, ring_peek() returns r->buf[(r->prod - -n) % RING_SIZE] instead of EOF. Currently harmless, because no caller peeks out of range. Signed-off-by: Markus Armbruster --- src/client/ringbuf.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/client/ringbuf.c b/src/client/ringbuf.c index c65ff211..1fb6bff6 100644 --- a/src/client/ringbuf.c +++ b/src/client/ringbuf.c @@ -27,7 +27,7 @@ * ringbuf.c: Simple ring buffer * * Known contributors to this file: - * Markus Armbruster, 2007-2009 + * Markus Armbruster, 2007-2015 */ #include @@ -82,9 +82,17 @@ ring_peek(struct ring *r, int n) assert(-RING_SIZE - 1 <= n && n <= RING_SIZE); - idx = n >= 0 ? r->cons + n : r->prod - -n; - if (idx < r->cons && idx >= r->prod) - return EOF; + if (n >= 0) { + idx = r->cons + n; + if (idx >= r->prod) + return EOF; + } else { + /* Beware, r->prod - -n can wrap around, avoid that */ + if (r->prod < r->cons + -n) + return EOF; + idx = r->prod - -n; + } + return r->buf[idx % RING_SIZE]; }