]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: fix a few bugs in ring buffers
authorQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 3 Jan 2018 18:58:53 +0000 (13:58 -0500)
committerQuentin Young <qlyoung@cumulusnetworks.com>
Wed, 3 Jan 2018 19:04:43 +0000 (14:04 -0500)
* Fix rare failure caused when end pointer is at end of buffer memory
  and a call to ringbuf_get() is made that reads all of the data in the
  buffer; start pointer was advanced past end pointer, causing some
  special handling to be skipped
* Fix ringbuf_peek() moving start pointer
* Fix use after free
* Remove extraneous assignment
* Update relevant tests

Signed-off-by: Quentin Young <qlyoung@cumulusnetworks.com>
lib/ringbuf.c
tests/lib/test_ringbuf.c

index d4efbe05fbf5e13f0dd9b9346c196faafa8ad30d..11db502a94870ae2069fe0d48137777c83132667 100644 (file)
@@ -58,7 +58,7 @@ size_t ringbuf_put(struct ringbuf *buf, const void *data, size_t size)
        size_t space = ringbuf_space(buf);
        size_t copysize = MIN(size, space);
        size_t tocopy = copysize;
-       if (tocopy > buf->size - buf->end) {
+       if (tocopy >= buf->size - buf->end) {
                size_t ts = buf->size - buf->end;
                memcpy(buf->data + buf->end, dp, ts);
                buf->end = 0;
@@ -102,7 +102,7 @@ size_t ringbuf_peek(struct ringbuf *buf, size_t offset, void *data, size_t size)
        if (tocopy >= buf->size - cstart) {
                size_t ts = buf->size - cstart;
                memcpy(dp, buf->data + cstart, ts);
-               buf->start = cstart = 0;
+               cstart = 0;
                tocopy -= ts;
                dp += ts;
        }
@@ -115,8 +115,9 @@ size_t ringbuf_copy(struct ringbuf *to, struct ringbuf *from, size_t size)
        size_t tocopy = MIN(ringbuf_space(to), size);
        uint8_t *cbuf = XCALLOC(MTYPE_TMP, tocopy);
        tocopy = ringbuf_peek(from, 0, cbuf, tocopy);
+       size_t put = ringbuf_put(to, cbuf, tocopy);
        XFREE(MTYPE_TMP, cbuf);
-       return ringbuf_put(to, cbuf, tocopy);
+       return put;
 }
 
 void ringbuf_reset(struct ringbuf *buf)
@@ -129,5 +130,4 @@ void ringbuf_wipe(struct ringbuf *buf)
 {
        memset(buf->data, 0x00, buf->size);
        ringbuf_reset(buf);
-       buf->empty = true;
 }
index c2f4f76a6fcaf70a52122e6e5bc2c2968e025129..7ba5a29b6225d55e106dd6996ed1bdca1269e3e2 100644 (file)
@@ -65,7 +65,7 @@ int main(int argc, char **argv)
 
        validate_state(soil, BUFSIZ, BUFSIZ);
        assert(soil->start == 0);
-       assert(soil->end == BUFSIZ);
+       assert(soil->end == 0);
 
        /* read 15 bytes of garbage */
        printf("Validating read...\n");
@@ -73,7 +73,7 @@ int main(int argc, char **argv)
 
        validate_state(soil, BUFSIZ, BUFSIZ - 15);
        assert(soil->start == 15);
-       assert(soil->end == BUFSIZ);
+       assert(soil->end == 0);
 
        /* put another 10 bytes and validate wraparound */
        printf("Validating wraparound...\n");