diff options
author | Wim Taymans <wtaymans@redhat.com> | 2017-11-13 11:50:50 +0100 |
---|---|---|
committer | Wim Taymans <wtaymans@redhat.com> | 2017-11-13 11:50:50 +0100 |
commit | 737b4280772a00d532f27d03cf369b70c53365a1 (patch) | |
tree | 243e3bf7d77cbeea122bb18aa1a7066abf22c9cc | |
parent | 101d2af1be6816ce82cdd748bfb650ac9049c232 (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.h | 28 | ||||
-rw-r--r-- | spa/plugins/alsa/alsa-utils.c | 2 | ||||
-rw-r--r-- | spa/plugins/v4l2/v4l2-source.c | 2 | ||||
-rw-r--r-- | spa/tests/test-props.c | 2 | ||||
-rw-r--r-- | spa/tests/test-props2.c | 2 | ||||
-rw-r--r-- | src/examples/video-play.c | 2 | ||||
-rw-r--r-- | src/gst/gstpipewireformat.c | 18 | ||||
-rw-r--r-- | src/gst/gstpipewiresink.c | 2 |
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(¶ms[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, |