mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-12 09:52:27 +00:00
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:
parent
cb94eaebff
commit
74e4a329a3
@ -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;
|
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
|
Loading…
Reference in New Issue
Block a user