mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2026-04-09 08:21:08 -04:00
mem: handle overflow in pw_map_range_init()
Integer overflows can result in map_range_init() to return wrong offset or size that can result in access to invalid or unmapped memory. Check for the overflows and return an EOVERFLOW error. Found by Claude Code.
This commit is contained in:
parent
d7be4353ad
commit
1a3df16e27
6 changed files with 96 additions and 10 deletions
|
|
@ -692,7 +692,10 @@ static int map_data(struct filter *impl, struct spa_data *data, int prot)
|
|||
void *ptr;
|
||||
struct pw_map_range range;
|
||||
|
||||
pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize);
|
||||
if (pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize) < 0) {
|
||||
pw_log_error("%p: invalid buffer map range", impl);
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
ptr = mmap(NULL, range.size, prot, MAP_SHARED, data->fd, range.offset);
|
||||
if (ptr == MAP_FAILED) {
|
||||
|
|
@ -721,7 +724,8 @@ static int unmap_data(struct filter *impl, struct spa_data *data)
|
|||
{
|
||||
struct pw_map_range range;
|
||||
|
||||
pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize);
|
||||
if (pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize) < 0)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (munmap(SPA_PTROFF(data->data, -range.start, void), range.size) < 0)
|
||||
pw_log_warn("%p: failed to unmap: %m", impl);
|
||||
|
|
|
|||
|
|
@ -421,7 +421,10 @@ struct pw_memmap * pw_memblock_map(struct pw_memblock *block,
|
|||
m = memblock_find_mapping(b, flags, offset, size);
|
||||
if (m == NULL) {
|
||||
struct pw_map_range range;
|
||||
pw_map_range_init(&range, offset, size, p->pagesize);
|
||||
if (pw_map_range_init(&range, offset, size, p->pagesize) < 0) {
|
||||
errno = EOVERFLOW;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
m = memblock_map(b, flags, range.offset, range.size);
|
||||
if (m == NULL)
|
||||
|
|
|
|||
|
|
@ -178,14 +178,21 @@ struct pw_map_range {
|
|||
#define PW_MAP_RANGE_INIT (struct pw_map_range){ 0, }
|
||||
|
||||
/** Calculate parameters to mmap() memory into \a range so that
|
||||
* \a size bytes at \a offset can be mapped with mmap(). */
|
||||
PW_API_MEM void pw_map_range_init(struct pw_map_range *range,
|
||||
* \a size bytes at \a offset can be mapped with mmap().
|
||||
* Returns 0 on success, -EOVERFLOW if offset + size overflows. */
|
||||
PW_API_MEM int pw_map_range_init(struct pw_map_range *range,
|
||||
uint32_t offset, uint32_t size,
|
||||
uint32_t page_size)
|
||||
{
|
||||
range->offset = SPA_ROUND_DOWN_N(offset, page_size);
|
||||
range->start = offset - range->offset;
|
||||
if (size > UINT32_MAX - range->start)
|
||||
return -EOVERFLOW;
|
||||
/* Check that rounding up to page_size won't overflow */
|
||||
if (range->start + size > UINT32_MAX - (page_size - 1))
|
||||
return -EOVERFLOW;
|
||||
range->size = SPA_ROUND_UP_N(range->start + size, page_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -807,7 +807,10 @@ static int map_data(struct stream *impl, struct spa_data *data, int prot)
|
|||
void *ptr;
|
||||
struct pw_map_range range;
|
||||
|
||||
pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize);
|
||||
if (pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize) < 0) {
|
||||
pw_log_error("%p: invalid buffer map range", impl);
|
||||
return -EOVERFLOW;
|
||||
}
|
||||
|
||||
ptr = mmap(NULL, range.size, prot, MAP_SHARED, data->fd, range.offset);
|
||||
if (ptr == MAP_FAILED) {
|
||||
|
|
@ -837,7 +840,8 @@ static int unmap_data(struct stream *impl, struct spa_data *data)
|
|||
{
|
||||
struct pw_map_range range;
|
||||
|
||||
pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize);
|
||||
if (pw_map_range_init(&range, data->mapoffset, data->maxsize, impl->context->sc_pagesize) < 0)
|
||||
return -EOVERFLOW;
|
||||
|
||||
if (munmap(SPA_PTROFF(data->data, -range.start, void), range.size) < 0)
|
||||
pw_log_warn("%p: failed to unmap: %m", impl);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue