mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-10-29 05:40:27 -04:00
pod: check that choices are not empty
Before using the contents of a choice, check that it is not empty to avoid reading out of bounds.
This commit is contained in:
parent
d37bdf5cbf
commit
b04da87e38
7 changed files with 18 additions and 4 deletions
|
|
@ -2311,6 +2311,8 @@ static int vidioc_s_ctrl(struct file *file, struct v4l2_control *arg)
|
||||||
struct spa_pod_frame f[1];
|
struct spa_pod_frame f[1];
|
||||||
struct spa_pod *param;
|
struct spa_pod *param;
|
||||||
pod = spa_pod_get_values(type, &n_vals, &choice);
|
pod = spa_pod_get_values(type, &n_vals, &choice);
|
||||||
|
if (n_vals < 1)
|
||||||
|
break;
|
||||||
|
|
||||||
spa_pod_builder_push_object(&b, &f[0],
|
spa_pod_builder_push_object(&b, &f[0],
|
||||||
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
|
SPA_TYPE_OBJECT_Props, SPA_PARAM_Props);
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ SPA_API_DEBUG_FORMAT int spa_debugc_format(struct spa_debug_context *ctx, int in
|
||||||
size = val->size;
|
size = val->size;
|
||||||
vals = SPA_POD_BODY(val);
|
vals = SPA_POD_BODY(val);
|
||||||
|
|
||||||
if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST)
|
if (type < SPA_TYPE_None || type >= _SPA_TYPE_LAST || n_vals < 1)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ti = spa_debug_type_find(info, prop->key);
|
ti = spa_debug_type_find(info, prop->key);
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,9 @@ SPA_API_POD_COMPARE int spa_pod_compare(const struct spa_pod *pod1,
|
||||||
if (pod1->type != pod2->type)
|
if (pod1->type != pod2->type)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (n_vals1 < 1)
|
||||||
|
return -EINVAL; /* empty choice */
|
||||||
|
|
||||||
switch (pod1->type) {
|
switch (pod1->type) {
|
||||||
case SPA_TYPE_Struct:
|
case SPA_TYPE_Struct:
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -80,8 +80,13 @@ spa_pod_filter_prop(struct spa_pod_builder *b,
|
||||||
int res, n_copied = 0;
|
int res, n_copied = 0;
|
||||||
|
|
||||||
v1 = spa_pod_get_values(&p1->value, &nalt1, &p1c);
|
v1 = spa_pod_get_values(&p1->value, &nalt1, &p1c);
|
||||||
alt1 = SPA_POD_BODY(v1);
|
|
||||||
v2 = spa_pod_get_values(&p2->value, &nalt2, &p2c);
|
v2 = spa_pod_get_values(&p2->value, &nalt2, &p2c);
|
||||||
|
|
||||||
|
/* empty choices */
|
||||||
|
if (nalt1 < 1 || nalt2 < 1)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
alt1 = SPA_POD_BODY(v1);
|
||||||
alt2 = SPA_POD_BODY(v2);
|
alt2 = SPA_POD_BODY(v2);
|
||||||
|
|
||||||
type = v1->type;
|
type = v1->type;
|
||||||
|
|
|
||||||
|
|
@ -72,7 +72,7 @@ spa_pod_simplify_merge(struct spa_pod_builder *b, const struct spa_pod *pod1, co
|
||||||
vals1 = spa_pod_get_values(&p1->value, &n_vals1, &choice1);
|
vals1 = spa_pod_get_values(&p1->value, &n_vals1, &choice1);
|
||||||
vals2 = spa_pod_get_values(&p2->value, &n_vals2, &choice2);
|
vals2 = spa_pod_get_values(&p2->value, &n_vals2, &choice2);
|
||||||
|
|
||||||
if (vals1->type != vals2->type)
|
if (vals1->type != vals2->type || n_vals1 < 1 || n_vals2 < 1)
|
||||||
goto error_einval;
|
goto error_einval;
|
||||||
|
|
||||||
size = vals1->size;
|
size = vals1->size;
|
||||||
|
|
|
||||||
|
|
@ -1209,6 +1209,9 @@ static struct spa_pod *transform_format(struct impl *this, struct port *port, co
|
||||||
uint32_t n_vals, choice, *id_vals;
|
uint32_t n_vals, choice, *id_vals;
|
||||||
struct spa_pod *val = spa_pod_get_values(&prop->value, &n_vals, &choice);
|
struct spa_pod *val = spa_pod_get_values(&prop->value, &n_vals, &choice);
|
||||||
|
|
||||||
|
if (n_vals < 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!spa_pod_is_id(val))
|
if (!spa_pod_is_id(val))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
|
@ -1311,7 +1314,7 @@ static int diff_prop(struct impl *impl, struct spa_pod_prop *prop,
|
||||||
void *vals, *v, *best = NULL;
|
void *vals, *v, *best = NULL;
|
||||||
int res = INT_MAX;
|
int res = INT_MAX;
|
||||||
|
|
||||||
if (val->type != type)
|
if (n_vals < 1 || val->type != type)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
size = SPA_POD_BODY_SIZE(val);
|
size = SPA_POD_BODY_SIZE(val);
|
||||||
|
|
|
||||||
|
|
@ -161,6 +161,7 @@ static void test_parse(void)
|
||||||
uint32_t n_vals, choice;
|
uint32_t n_vals, choice;
|
||||||
struct spa_pod *pod = spa_pod_get_values(&prop->value, &n_vals, &choice);
|
struct spa_pod *pod = spa_pod_get_values(&prop->value, &n_vals, &choice);
|
||||||
|
|
||||||
|
spa_assert_se(n_vals > 0);
|
||||||
switch(prop->key) {
|
switch(prop->key) {
|
||||||
case SPA_FORMAT_mediaType:
|
case SPA_FORMAT_mediaType:
|
||||||
spa_pod_get_id(pod, &vals.media_type);
|
spa_pod_get_id(pod, &vals.media_type);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue