From 289b33281fb089620a6a9edb200e880493176fd1 Mon Sep 17 00:00:00 2001 From: Wim Taymans Date: Mon, 7 Jul 2025 19:40:24 +0200 Subject: [PATCH] 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. --- spa/include/spa/pod/compare.h | 18 ++++++++++++++++++ spa/include/spa/pod/filter.h | 12 +++++++++--- 2 files changed, 27 insertions(+), 3 deletions(-) diff --git a/spa/include/spa/pod/compare.h b/spa/include/spa/pod/compare.h index 96de89d24..1c043927e 100644 --- a/spa/include/spa/pod/compare.h +++ b/spa/include/spa/pod/compare.h @@ -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); diff --git a/spa/include/spa/pod/filter.h b/spa/include/spa/pod/filter.h index 699bddc27..6c92e910d 100644 --- a/spa/include/spa/pod/filter.h +++ b/spa/include/spa/pod/filter.h @@ -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);