lib: fix a few bugs in ring buffers

* 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>
This commit is contained in:
Quentin Young 2018-01-03 13:58:53 -05:00
parent cb94eaebff
commit 74e4a329a3
No known key found for this signature in database
GPG Key ID: DAF48E0F57E0834F
2 changed files with 6 additions and 6 deletions

View 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 space = ringbuf_space(buf);
size_t copysize = MIN(size, space); size_t copysize = MIN(size, space);
size_t tocopy = copysize; size_t tocopy = copysize;
if (tocopy > buf->size - buf->end) { if (tocopy >= buf->size - buf->end) {
size_t ts = buf->size - buf->end; size_t ts = buf->size - buf->end;
memcpy(buf->data + buf->end, dp, ts); memcpy(buf->data + buf->end, dp, ts);
buf->end = 0; 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) { if (tocopy >= buf->size - cstart) {
size_t ts = buf->size - cstart; size_t ts = buf->size - cstart;
memcpy(dp, buf->data + cstart, ts); memcpy(dp, buf->data + cstart, ts);
buf->start = cstart = 0; cstart = 0;
tocopy -= ts; tocopy -= ts;
dp += 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); size_t tocopy = MIN(ringbuf_space(to), size);
uint8_t *cbuf = XCALLOC(MTYPE_TMP, tocopy); uint8_t *cbuf = XCALLOC(MTYPE_TMP, tocopy);
tocopy = ringbuf_peek(from, 0, cbuf, tocopy); tocopy = ringbuf_peek(from, 0, cbuf, tocopy);
size_t put = ringbuf_put(to, cbuf, tocopy);
XFREE(MTYPE_TMP, cbuf); XFREE(MTYPE_TMP, cbuf);
return ringbuf_put(to, cbuf, tocopy); return put;
} }
void ringbuf_reset(struct ringbuf *buf) void ringbuf_reset(struct ringbuf *buf)
@ -129,5 +130,4 @@ void ringbuf_wipe(struct ringbuf *buf)
{ {
memset(buf->data, 0x00, buf->size); memset(buf->data, 0x00, buf->size);
ringbuf_reset(buf); ringbuf_reset(buf);
buf->empty = true;
} }

View File

@ -65,7 +65,7 @@ int main(int argc, char **argv)
validate_state(soil, BUFSIZ, BUFSIZ); validate_state(soil, BUFSIZ, BUFSIZ);
assert(soil->start == 0); assert(soil->start == 0);
assert(soil->end == BUFSIZ); assert(soil->end == 0);
/* read 15 bytes of garbage */ /* read 15 bytes of garbage */
printf("Validating read...\n"); printf("Validating read...\n");
@ -73,7 +73,7 @@ int main(int argc, char **argv)
validate_state(soil, BUFSIZ, BUFSIZ - 15); validate_state(soil, BUFSIZ, BUFSIZ - 15);
assert(soil->start == 15); assert(soil->start == 15);
assert(soil->end == BUFSIZ); assert(soil->end == 0);
/* put another 10 bytes and validate wraparound */ /* put another 10 bytes and validate wraparound */
printf("Validating wraparound...\n"); printf("Validating wraparound...\n");