mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
pod: Check that choices have enough values for their kind
Prevent out of bounds reads when a choice is too small for the type of choice that it is. Add a utility function to help catch this case.
This commit is contained in:
parent
5853e1150b
commit
fcfe01a0be
3 changed files with 26 additions and 2 deletions
|
|
@ -116,6 +116,27 @@ SPA_API_POD_BODY uint32_t spa_pod_type_align(uint32_t type)
|
|||
}
|
||||
}
|
||||
|
||||
SPA_API_POD_BODY uint32_t spa_pod_choice_min_values(uint32_t choice_type)
|
||||
{
|
||||
switch (choice_type) {
|
||||
case SPA_CHOICE_Enum:
|
||||
return 2;
|
||||
case SPA_CHOICE_Range:
|
||||
return 3;
|
||||
case SPA_CHOICE_Step:
|
||||
return 4;
|
||||
case SPA_CHOICE_None:
|
||||
case SPA_CHOICE_Flags:
|
||||
default:
|
||||
/*
|
||||
* This must always return at least 1, because callers
|
||||
* assume that n_vals >= spa_pod_choice_min_values()
|
||||
* mean that n_vals is at least 1.
|
||||
*/
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
SPA_API_POD_BODY int spa_pod_body_from_data(void *data, size_t maxsize, off_t offset, size_t size,
|
||||
struct spa_pod *pod, const void **body)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -226,6 +226,8 @@ SPA_API_POD_COMPARE int spa_pod_compare_is_in_range(uint32_t type, const void *v
|
|||
SPA_API_POD_COMPARE int spa_pod_compare_is_valid_choice(uint32_t type, uint32_t size,
|
||||
const void *val, const void *vals, uint32_t n_vals, uint32_t choice)
|
||||
{
|
||||
if (n_vals < spa_pod_choice_min_values(choice))
|
||||
return 0;
|
||||
switch (choice) {
|
||||
case SPA_CHOICE_None:
|
||||
if (spa_pod_compare_value(type, val, vals, size) == 0)
|
||||
|
|
|
|||
|
|
@ -83,7 +83,8 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
|||
v2 = spa_pod_get_values(&p2->value, &nalt2, &p2c);
|
||||
|
||||
/* empty or bogus choices */
|
||||
if (nalt1 < 1 || nalt2 < 1)
|
||||
if (nalt1 < spa_pod_choice_min_values(p1c) ||
|
||||
nalt2 < spa_pod_choice_min_values(p2c))
|
||||
return -EINVAL;
|
||||
|
||||
alt1 = SPA_POD_BODY(v1);
|
||||
|
|
@ -403,7 +404,7 @@ SPA_API_POD_FILTER int spa_pod_filter_object_make(struct spa_pod_object *pod)
|
|||
struct spa_pod *v = spa_pod_get_values(&res->value, &nvals, &choice);
|
||||
const void *vals = SPA_POD_BODY(v);
|
||||
|
||||
if (nvals < 1)
|
||||
if (nvals < spa_pod_choice_min_values(choice))
|
||||
continue;
|
||||
|
||||
if (spa_pod_compare_is_valid_choice(v->type, v->size,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue