From 9e789c65c22e5671d88dc32006e2f32a563e340f Mon Sep 17 00:00:00 2001 From: Demi Marie Obenour Date: Sun, 20 Jul 2025 15:06:49 -0400 Subject: [PATCH] src: check that POD arrays have the correct size for their type The parser does not check that POD arrays have the correct size for their type, so the calling code must do that. This also enumerates some of the code that cannot handle the size of the values of an array not being the exact expected size for its type. There is a lot of it. --- .../module-protocol-native/protocol-native.c | 6 ++--- src/modules/module-protocol-pulse/collect.c | 24 +++++++++++++------ .../module-session-manager/protocol-native.c | 16 ++++++------- src/pipewire/stream.c | 7 +++--- 4 files changed, 32 insertions(+), 21 deletions(-) diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 3a7a1a179..3a8580efb 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -977,7 +977,7 @@ static int device_demarshal_subscribe_params(void *object, const struct pw_proto SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_device_methods, subscribe_params, 0, @@ -1238,7 +1238,7 @@ static int node_demarshal_subscribe_params(void *object, const struct pw_protoco SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_node_methods, subscribe_params, 0, @@ -1462,7 +1462,7 @@ static int port_demarshal_subscribe_params(void *object, const struct pw_protoco SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_port_methods, subscribe_params, 0, diff --git a/src/modules/module-protocol-pulse/collect.c b/src/modules/module-protocol-pulse/collect.c index 1f0578026..a02f82f62 100644 --- a/src/modules/module-protocol-pulse/collect.c +++ b/src/modules/module-protocol-pulse/collect.c @@ -369,7 +369,9 @@ uint32_t collect_port_info(struct pw_manager_object *card, struct card_info *car n = 0; spa_list_for_each(p, &card->param_list, link) { - struct spa_pod *devices = NULL, *profiles = NULL; + int32_t *devices = NULL, *profiles = NULL; + uint32_t devices_size = 0, devices_type = 0, n_devices = 0; + uint32_t profiles_size = 0, profiles_type = 0, n_profiles = 0; struct port_info *pi; if (p->id != SPA_PARAM_EnumRoute) @@ -387,16 +389,24 @@ uint32_t collect_port_info(struct pw_manager_object *card, struct card_info *car SPA_PARAM_ROUTE_priority, SPA_POD_OPT_Int(&pi->priority), SPA_PARAM_ROUTE_available, SPA_POD_OPT_Id(&pi->available), SPA_PARAM_ROUTE_info, SPA_POD_OPT_Pod(&pi->info), - SPA_PARAM_ROUTE_devices, SPA_POD_OPT_Pod(&devices), - SPA_PARAM_ROUTE_profiles, SPA_POD_OPT_Pod(&profiles)) < 0) + SPA_PARAM_ROUTE_devices, SPA_POD_OPT_Array(&devices_size, + &devices_type, &n_devices, &devices), + SPA_PARAM_ROUTE_profiles, SPA_POD_OPT_Array(&profiles_size, + &profiles_type, &n_profiles, &profiles)) < 0) continue; if (pi->description == NULL) pi->description = pi->name; - if (devices) - pi->devices = spa_pod_get_array(devices, &pi->n_devices); - if (profiles) - pi->profiles = spa_pod_get_array(profiles, &pi->n_profiles); + if (devices && devices_size == sizeof(pi->devices[0]) && + devices_type == SPA_TYPE_Int) { + pi->devices = devices; + pi->n_devices = n_devices; + } + if (profiles && profiles_size == sizeof(pi->profiles[0]) && + profiles_type == SPA_TYPE_Int) { + pi->profiles = profiles; + pi->n_profiles = n_profiles; + } if (dev_info != NULL) { if (pi->direction != dev_info->direction) diff --git a/src/modules/module-session-manager/protocol-native.c b/src/modules/module-session-manager/protocol-native.c index 98be24429..01be455ae 100644 --- a/src/modules/module-session-manager/protocol-native.c +++ b/src/modules/module-session-manager/protocol-native.c @@ -1284,7 +1284,7 @@ static int endpoint_link_proxy_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_proxy_notify(proxy, struct pw_endpoint_link_methods, @@ -1304,7 +1304,7 @@ static int endpoint_link_resource_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_endpoint_link_methods, @@ -1806,7 +1806,7 @@ static int endpoint_stream_proxy_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_proxy_notify(proxy, struct pw_endpoint_stream_methods, @@ -1826,7 +1826,7 @@ static int endpoint_stream_resource_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_endpoint_stream_methods, @@ -2320,7 +2320,7 @@ static int endpoint_proxy_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_proxy_notify(proxy, struct pw_endpoint_methods, @@ -2340,7 +2340,7 @@ static int endpoint_resource_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_endpoint_methods, @@ -2842,7 +2842,7 @@ static int session_proxy_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_proxy_notify(proxy, struct pw_session_methods, @@ -2862,7 +2862,7 @@ static int session_resource_demarshal_subscribe_params(void *object, SPA_POD_Array(&csize, &ctype, &n_ids, &ids)) < 0) return -EINVAL; - if (ctype != SPA_TYPE_Id) + if (ctype != SPA_TYPE_Id || csize != sizeof(uint32_t)) return -EINVAL; return pw_resource_notify(resource, struct pw_session_methods, diff --git a/src/pipewire/stream.c b/src/pipewire/stream.c index 8cdef61ad..ddd53ebd0 100644 --- a/src/pipewire/stream.c +++ b/src/pipewire/stream.c @@ -1347,7 +1347,7 @@ static int node_event_param(void *object, int seq, double value_d; bool value_b; float *values; - uint32_t i, n_values; + uint32_t i, n_values, val_size, val_type; SPA_POD_OBJECT_FOREACH(obj, prop) { struct control *c; @@ -1378,8 +1378,9 @@ static int node_event_param(void *object, int seq, values = &value_f; break; case SPA_TYPE_Array: - if ((values = spa_pod_get_array(&prop->value, &n_values)) == NULL || - !spa_pod_is_float(SPA_POD_ARRAY_CHILD(&prop->value))) + if ((values = spa_pod_get_array_full(&prop->value, &n_values, &val_size, &val_type)) == NULL || + val_type != SPA_TYPE_Float || + val_size != sizeof(float)) continue; n_values = SPA_MIN(n_values, MAX_VALUES); break;