pod: check size before getting pod contents

Before accessing the pod contents, check if the size is at least what we
expect it to be or else we might read out of bounds.
This commit is contained in:
Wim Taymans 2025-07-07 19:40:24 +02:00
parent 8aa836d588
commit 289b33281f
2 changed files with 27 additions and 3 deletions

View file

@ -39,23 +39,39 @@ SPA_API_POD_COMPARE int spa_pod_compare_value(uint32_t type, const void *r1, con
case SPA_TYPE_None:
return 0;
case SPA_TYPE_Bool:
if (size < sizeof(int32_t))
return -EINVAL;
return SPA_CMP(!!*(int32_t *)r1, !!*(int32_t *)r2);
case SPA_TYPE_Id:
if (size < sizeof(uint32_t))
return -EINVAL;
return SPA_CMP(*(uint32_t *)r1, *(uint32_t *)r2);
case SPA_TYPE_Int:
if (size < sizeof(int32_t))
return -EINVAL;
return SPA_CMP(*(int32_t *)r1, *(int32_t *)r2);
case SPA_TYPE_Long:
if (size < sizeof(int64_t))
return -EINVAL;
return SPA_CMP(*(int64_t *)r1, *(int64_t *)r2);
case SPA_TYPE_Float:
if (size < sizeof(float))
return -EINVAL;
return SPA_CMP(*(float *)r1, *(float *)r2);
case SPA_TYPE_Double:
if (size < sizeof(double))
return -EINVAL;
return SPA_CMP(*(double *)r1, *(double *)r2);
case SPA_TYPE_String:
if (size < sizeof(char))
return -EINVAL;
return strcmp((char *)r1, (char *)r2);
case SPA_TYPE_Rectangle:
{
const struct spa_rectangle *rec1 = (struct spa_rectangle *) r1,
*rec2 = (struct spa_rectangle *) r2;
if (size < sizeof(struct spa_rectangle))
return -EINVAL;
if (rec1->width == rec2->width && rec1->height == rec2->height)
return 0;
else if (rec1->width < rec2->width || rec1->height < rec2->height)
@ -68,6 +84,8 @@ SPA_API_POD_COMPARE int spa_pod_compare_value(uint32_t type, const void *r1, con
const struct spa_fraction *f1 = (struct spa_fraction *) r1,
*f2 = (struct spa_fraction *) r2;
uint64_t n1, n2;
if (size < sizeof(struct spa_fraction))
return -EINVAL;
n1 = ((uint64_t) f1->num) * f2->denom;
n2 = ((uint64_t) f2->num) * f1->denom;
return SPA_CMP(n1, n2);

View file

@ -35,12 +35,15 @@ extern "C" {
*/
SPA_API_POD_FILTER int spa_pod_filter_flags_value(struct spa_pod_builder *b,
uint32_t type, const void *r1, const void *r2, uint32_t size SPA_UNUSED)
uint32_t type, const void *r1, const void *r2, uint32_t size)
{
switch (type) {
case SPA_TYPE_Int:
{
int32_t val = (*(int32_t *) r1) & (*(int32_t *) r2);
int32_t val;
if (size < sizeof(int32_t))
return -EINVAL;
val = (*(int32_t *) r1) & (*(int32_t *) r2);
if (val == 0)
return 0;
spa_pod_builder_int(b, val);
@ -48,7 +51,10 @@ SPA_API_POD_FILTER int spa_pod_filter_flags_value(struct spa_pod_builder *b,
}
case SPA_TYPE_Long:
{
int64_t val = (*(int64_t *) r1) & (*(int64_t *) r2);
int64_t val;
if (size < sizeof(int64_t))
return -EINVAL;
val = (*(int64_t *) r1) & (*(int64_t *) r2);
if (val == 0)
return 0;
spa_pod_builder_long(b, val);