From bf9ef440c3c69a31918b8a3a02c07dad2cbf5cf7 Mon Sep 17 00:00:00 2001 From: Pauli Virtanen Date: Sun, 20 Feb 2022 18:13:22 +0200 Subject: [PATCH] protocol-native: check invariant for marshaled data There's an assumption that marshaled messages consist of a single POD, since we now tag on a footer after it. This is true for the protocol-native implementations, which all wrap the message in a single POD Struct. To catch protocol-native implementation bugs here later, add assert that marshaling produces a single POD. --- src/modules/module-protocol-native.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/modules/module-protocol-native.c b/src/modules/module-protocol-native.c index 6db586e50..e7112dfff 100644 --- a/src/modules/module-protocol-native.c +++ b/src/modules/module-protocol-native.c @@ -1277,11 +1277,24 @@ static int impl_ext_get_proxy_fd(struct pw_proxy *proxy, uint32_t index) return pw_protocol_native_connection_get_fd(impl->connection, index); } +static void assert_single_pod(struct spa_pod_builder *builder) +{ + /* + * Check the invariant that the message we just marshaled + * consists of at most one POD. + */ + struct spa_pod *pod = builder->data; + spa_assert(builder->data == NULL || + builder->state.offset < sizeof(struct spa_pod) || + builder->state.offset == SPA_POD_SIZE(pod)); +} + static int impl_ext_end_proxy(struct pw_proxy *proxy, struct spa_pod_builder *builder) { struct pw_core *core = proxy->core; struct client *impl = SPA_CONTAINER_OF(core->conn, struct client, this); + assert_single_pod(builder); marshal_proxy_footers(&impl->footer_state, proxy, builder); return core->send_seq = pw_protocol_native_connection_end(impl->connection, builder); } @@ -1310,6 +1323,7 @@ static int impl_ext_end_resource(struct pw_resource *resource, { struct client_data *data = resource->client->user_data; struct pw_impl_client *client = resource->client; + assert_single_pod(builder); marshal_resource_footers(&data->footer_state, resource, builder); return client->send_seq = pw_protocol_native_connection_end(data->connection, builder); }