summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWim Taymans <wtaymans@redhat.com>2017-11-13 11:50:50 +0100
committerWim Taymans <wtaymans@redhat.com>2017-11-13 11:50:50 +0100
commit737b4280772a00d532f27d03cf369b70c53365a1 (patch)
tree243e3bf7d77cbeea122bb18aa1a7066abf22c9cc
parent101d2af1be6816ce82cdd748bfb650ac9049c232 (diff)
builder: make deref safer
Don't try to deref objects that did not fit into the memory. Deref now returns the object
-rw-r--r--spa/include/spa/pod/builder.h28
-rw-r--r--spa/plugins/alsa/alsa-utils.c2
-rw-r--r--spa/plugins/v4l2/v4l2-source.c2
-rw-r--r--spa/tests/test-props.c2
-rw-r--r--spa/tests/test-props2.c2
-rw-r--r--src/examples/video-play.c2
-rw-r--r--src/gst/gstpipewireformat.c18
-rw-r--r--src/gst/gstpipewiresink.c2
8 files changed, 32 insertions, 26 deletions
diff --git a/spa/include/spa/pod/builder.h b/spa/include/spa/pod/builder.h
index d013598b..c8b65fd7 100644
--- a/spa/include/spa/pod/builder.h
+++ b/spa/include/spa/pod/builder.h
@@ -67,10 +67,16 @@ static inline void spa_pod_builder_init(struct spa_pod_builder *builder, void *d
static inline void *
spa_pod_builder_deref(struct spa_pod_builder *builder, uint32_t ref)
{
- if (builder->deref)
+ if (ref == -1)
+ return NULL;
+ else if (builder->deref)
return builder->deref(builder, ref);
- else
- return SPA_MEMBER(builder->data, ref, void);
+ else if (ref + 8 <= builder->size) {
+ struct spa_pod *pod = SPA_MEMBER(builder->data, ref, struct spa_pod);
+ if (SPA_POD_SIZE(pod) <= builder->size)
+ return pod;
+ }
+ return NULL;
}
static inline uint32_t
@@ -126,25 +132,23 @@ spa_pod_builder_raw_padded(struct spa_pod_builder *builder, const void *data, ui
return ref;
}
-static inline uint32_t spa_pod_builder_pop(struct spa_pod_builder *builder)
+static inline void *spa_pod_builder_pop(struct spa_pod_builder *builder)
{
- struct spa_pod_frame *frame = &builder->frame[--builder->depth], *top;
+ struct spa_pod_frame *frame, *top;
+ struct spa_pod *pod;
- if (frame->ref != -1) {
- struct spa_pod *pod = spa_pod_builder_deref(builder, frame->ref);
+ frame = &builder->frame[--builder->depth];
+ if ((pod = spa_pod_builder_deref(builder, frame->ref)) != NULL)
*pod = frame->pod;
- }
+
top = builder->depth > 0 ? &builder->frame[builder->depth-1] : NULL;
builder->in_array = (top && (top->pod.type == SPA_POD_TYPE_ARRAY ||
top->pod.type == SPA_POD_TYPE_PROP));
spa_pod_builder_pad(builder, builder->offset);
- return frame->ref;
+ return pod;
}
-#define spa_pod_builder_pop_deref(b) \
- spa_pod_builder_deref((b), spa_pod_builder_pop(b))
-
static inline uint32_t
spa_pod_builder_primitive(struct spa_pod_builder *builder, const struct spa_pod *p)
{
diff --git a/spa/plugins/alsa/alsa-utils.c b/spa/plugins/alsa/alsa-utils.c
index 938c075d..bba4383b 100644
--- a/spa/plugins/alsa/alsa-utils.c
+++ b/spa/plugins/alsa/alsa-utils.c
@@ -189,7 +189,7 @@ spa_alsa_enum_format(struct state *state, uint32_t *index,
}
spa_pod_builder_pop(&b);
- fmt = spa_pod_builder_pop_deref(&b);
+ fmt = spa_pod_builder_pop(&b);
(*index)++;
diff --git a/spa/plugins/v4l2/v4l2-source.c b/spa/plugins/v4l2/v4l2-source.c
index fc473798..d494c9ad 100644
--- a/spa/plugins/v4l2/v4l2-source.c
+++ b/spa/plugins/v4l2/v4l2-source.c
@@ -503,7 +503,7 @@ static int port_get_format(struct spa_node *node,
} else
return -EIO;
- *param = spa_pod_builder_pop_deref(builder);
+ *param = spa_pod_builder_pop(builder);
return 1;
}
diff --git a/spa/tests/test-props.c b/spa/tests/test-props.c
index eb1d5ed5..dcb2fca2 100644
--- a/spa/tests/test-props.c
+++ b/spa/tests/test-props.c
@@ -315,7 +315,7 @@ int main(int argc, char *argv[])
spa_pod_builder_raw(&b, rate_min_max, sizeof(rate_min_max));
spa_pod_builder_pop(&b);
- fmt = spa_pod_builder_pop_deref(&b);
+ fmt = spa_pod_builder_pop(&b);
spa_debug_pod(&fmt->pod, 0);
diff --git a/spa/tests/test-props2.c b/spa/tests/test-props2.c
index ed014b71..aaa65a55 100644
--- a/spa/tests/test-props2.c
+++ b/spa/tests/test-props2.c
@@ -84,7 +84,7 @@ int main(int argc, char *argv[])
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b);
spa_pod_builder_pop(&b);
- obj = spa_pod_builder_pop_deref(&b);
+ obj = spa_pod_builder_pop(&b);
spa_debug_pod(obj, 0);
diff --git a/src/examples/video-play.c b/src/examples/video-play.c
index d4e4a657..11bf2a9f 100644
--- a/src/examples/video-play.c
+++ b/src/examples/video-play.c
@@ -348,7 +348,7 @@ static void on_state_changed(void *_data, enum pw_remote_state old, enum pw_remo
2, &SPA_RECTANGLE(0,1),
&SPA_RECTANGLE(30,1),
NULL);
- params[0] = spa_pod_builder_pop_deref(&b);
+ params[0] = spa_pod_builder_pop(&b);
printf("supported formats:\n");
spa_debug_pod(&params[0]->pod, SPA_DEBUG_FLAG_FORMAT);
diff --git a/src/gst/gstpipewireformat.c b/src/gst/gstpipewireformat.c
index 0368c0a5..9717a5e4 100644
--- a/src/gst/gstpipewireformat.c
+++ b/src/gst/gstpipewireformat.c
@@ -390,7 +390,7 @@ handle_video_fields (ConvertData *d)
if (idx < SPA_N_ELEMENTS (video_format_map))
spa_pod_builder_id (&d->b, *video_format_map[idx]);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -406,7 +406,7 @@ handle_video_fields (ConvertData *d)
spa_pod_builder_rectangle (&d->b, v.width, v.height);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -422,7 +422,7 @@ handle_video_fields (ConvertData *d)
spa_pod_builder_fraction (&d->b, v.num, v.denom);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -438,7 +438,7 @@ handle_video_fields (ConvertData *d)
spa_pod_builder_fraction (&d->b, v.num, v.denom);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -466,7 +466,7 @@ handle_audio_fields (ConvertData *d)
if (idx < SPA_N_ELEMENTS (audio_format_map))
spa_pod_builder_id (&d->b, *audio_format_map[idx]);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -491,7 +491,7 @@ handle_audio_fields (ConvertData *d)
spa_pod_builder_int (&d->b, layout);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -506,7 +506,7 @@ handle_audio_fields (ConvertData *d)
spa_pod_builder_int (&d->b, v);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -521,7 +521,7 @@ handle_audio_fields (ConvertData *d)
spa_pod_builder_int (&d->b, v);
}
- prop = spa_pod_builder_pop_deref(&d->b);
+ prop = spa_pod_builder_pop(&d->b);
if (i > 1)
prop->body.flags |= SPA_POD_PROP_FLAG_UNSET;
}
@@ -536,6 +536,8 @@ write_pod (struct spa_pod_builder *b, const void *data, uint32_t size)
if (b->size <= b->offset) {
b->size = SPA_ROUND_UP_N (b->offset + size, 512);
b->data = realloc (b->data, b->size);
+ if (b->data == NULL)
+ return -1;
}
memcpy (b->data + ref, data, size);
return ref;
diff --git a/src/gst/gstpipewiresink.c b/src/gst/gstpipewiresink.c
index 0081c3d4..b49d9e38 100644
--- a/src/gst/gstpipewiresink.c
+++ b/src/gst/gstpipewiresink.c
@@ -247,7 +247,7 @@ pool_activated (GstPipeWirePool *pool, GstPipeWireSink *sink)
max_buffers ? max_buffers : INT32_MAX),
":", t->param_buffers.align, "i", 16,
NULL);
- port_params[0] = spa_pod_builder_pop_deref (&b);
+ port_params[0] = spa_pod_builder_pop (&b);
port_params[1] = spa_pod_builder_object (&b,
t->param.idMeta, t->param_meta.Meta,