mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-31 22:25:38 -04:00
loop: Fix crash because of overflow
Also check if there is enough space to write the payload bytes. We check if there is enough space for the invoke_item structure first. Then we calculate how much bytes we need to use for the payload but we fail to check if we can actually write that much data, risking overwriting existing data from the ringbuffer and causing a crash later when we try to jump to invalid memory. Add some more comments.
This commit is contained in:
parent
327ec4306f
commit
7f4fa64291
1 changed files with 14 additions and 1 deletions
|
|
@ -182,6 +182,8 @@ loop_invoke(void *object,
|
|||
}
|
||||
offset = idx & (DATAS_SIZE - 1);
|
||||
|
||||
/* l0 is remaining size in ringbuffer, this should always be larger than
|
||||
* invoke_item, see below */
|
||||
l0 = DATAS_SIZE - offset;
|
||||
|
||||
item = SPA_PTROFF(impl->buffer_data, offset, struct invoke_item);
|
||||
|
|
@ -194,14 +196,25 @@ loop_invoke(void *object,
|
|||
spa_log_trace(impl->log, NAME " %p: add item %p filled:%d", impl, item, filled);
|
||||
|
||||
if (l0 > sizeof(struct invoke_item) + size) {
|
||||
/* item + size fit in current ringbuffer idx */
|
||||
item->data = SPA_PTROFF(item, sizeof(struct invoke_item), void);
|
||||
item->item_size = SPA_ROUND_UP_N(sizeof(struct invoke_item) + size, 8);
|
||||
if (l0 < sizeof(struct invoke_item) + item->item_size)
|
||||
if (l0 < sizeof(struct invoke_item) + item->item_size) {
|
||||
/* not enough space for next invoke_item, fill up till the end
|
||||
* so that the next item will be at the start */
|
||||
item->item_size = l0;
|
||||
}
|
||||
} else {
|
||||
/* item does not fit, place the invoke_item at idx and start the
|
||||
* data at the start of the ringbuffer */
|
||||
item->data = impl->buffer_data;
|
||||
item->item_size = SPA_ROUND_UP_N(l0 + size, 8);
|
||||
}
|
||||
if (avail < item->item_size) {
|
||||
spa_log_warn(impl->log, NAME " %p: queue full %d, need %zd", impl, avail,
|
||||
item->item_size);
|
||||
return -EPIPE;
|
||||
}
|
||||
if (data && size > 0)
|
||||
memcpy(item->data, data, size);
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue