diff --git a/src/modules/module-client-device/protocol-native.c b/src/modules/module-client-device/protocol-native.c index eb146cc86..b502170cc 100644 --- a/src/modules/module-client-device/protocol-native.c +++ b/src/modules/module-client-device/protocol-native.c @@ -32,6 +32,9 @@ #include +#define MAX_DICT 256 +#define MAX_PARAM_INFO 128 + static inline void push_item(struct spa_pod_builder *b, const struct spa_dict_item *item) { const char *str; @@ -62,6 +65,8 @@ do { \ SPA_POD_Int(&(d)->n_items), NULL) < 0) \ return -EINVAL; \ if ((d)->n_items > 0) { \ + if ((d)->n_items > MAX_DICT) \ + return -ENOSPC; \ (d)->items = alloca((d)->n_items * sizeof(struct spa_dict_item)); \ for (i = 0; i < (d)->n_items; i++) { \ if (parse_item(prs, (struct spa_dict_item *) &(d)->items[i]) < 0) \ @@ -77,6 +82,8 @@ do { \ SPA_POD_Int(&(n_params)), NULL) < 0) \ return -EINVAL; \ if (n_params > 0) { \ + if (n_params > MAX_PARAM_INFO) \ + return -ENOSPC; \ params = alloca(n_params * sizeof(struct spa_param_info)); \ for (i = 0; i < n_params; i++) { \ if (spa_pod_parser_get(prs, \ diff --git a/src/modules/module-client-node/client-node.c b/src/modules/module-client-node/client-node.c index dbfa91ea5..6bb24951e 100644 --- a/src/modules/module-client-node/client-node.c +++ b/src/modules/module-client-node/client-node.c @@ -755,6 +755,9 @@ do_port_use_buffers(struct impl *impl, if (!CHECK_PORT(this, direction, port_id)) return n_buffers == 0 ? 0 : -EINVAL; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + p = GET_PORT(this, direction, port_id); spa_log_debug(this->log, "%p: %s port %d.%d use buffers %p %u flags:%08x", this, diff --git a/src/modules/module-client-node/protocol-native.c b/src/modules/module-client-node/protocol-native.c index ac41d04ed..ce9576dc3 100644 --- a/src/modules/module-client-node/protocol-native.c +++ b/src/modules/module-client-node/protocol-native.c @@ -33,6 +33,13 @@ #include #include +#define MAX_DICT 256 +#define MAX_PARAMS 128 +#define MAX_PARAM_INFO 128 +#define MAX_BUFFERS 64 +#define MAX_METAS 16u +#define MAX_DATAS 64u + PW_LOG_TOPIC_EXTERN(mod_topic); #define PW_LOG_TOPIC_DEFAULT mod_topic @@ -81,6 +88,8 @@ do { \ return -EINVAL; \ (d)->items = NULL; \ if ((d)->n_items > 0) { \ + if ((d)->n_items > MAX_DICT) \ + return -ENOSPC; \ (d)->items = alloca((d)->n_items * sizeof(struct spa_dict_item)); \ for (i = 0; i < (d)->n_items; i++) { \ if (parse_item(prs, (struct spa_dict_item *) &(d)->items[i]) < 0) \ @@ -105,7 +114,9 @@ do { \ return -EINVAL; \ params = NULL; \ if (n_params > 0) { \ - params = alloca(n_params * sizeof(struct spa_pos *)); \ + if (n_params > MAX_PARAMS) \ + return -ENOSPC; \ + params = alloca(n_params * sizeof(struct spa_pod *)); \ for (i = 0; i < n_params; i++) { \ if (spa_pod_parser_get(prs, \ SPA_POD_PodObject(¶ms[i]), NULL) < 0) \ @@ -122,6 +133,8 @@ do { \ return -EINVAL; \ params = NULL; \ if (n_params > 0) { \ + if (n_params > MAX_PARAM_INFO) \ + return -ENOSPC; \ params = alloca(n_params * sizeof(struct spa_param_info)); \ for (i = 0; i < n_params; i++) { \ if (spa_pod_parser_get(prs, \ @@ -518,6 +531,9 @@ static int client_node_demarshal_port_use_buffers(void *object, const struct pw_ SPA_POD_Int(&n_buffers), NULL) < 0) return -EINVAL; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + buffers = alloca(sizeof(struct pw_client_node_buffer) * n_buffers); for (i = 0; i < n_buffers; i++) { struct spa_buffer *buf = buffers[i].buffer = alloca(sizeof(struct spa_buffer)); @@ -529,6 +545,9 @@ static int client_node_demarshal_port_use_buffers(void *object, const struct pw_ SPA_POD_Int(&buf->n_metas), NULL) < 0) return -EINVAL; + if (buf->n_metas > MAX_METAS) + return -ENOSPC; + buf->metas = alloca(sizeof(struct spa_meta) * buf->n_metas); for (j = 0; j < buf->n_metas; j++) { struct spa_meta *m = &buf->metas[j]; @@ -542,6 +561,9 @@ static int client_node_demarshal_port_use_buffers(void *object, const struct pw_ SPA_POD_Int(&buf->n_datas), NULL) < 0) return -EINVAL; + if (buf->n_datas > MAX_DATAS) + return -ENOSPC; + buf->datas = alloca(sizeof(struct spa_data) * buf->n_datas); for (j = 0; j < buf->n_datas; j++) { struct spa_data *d = &buf->datas[j]; @@ -1113,6 +1135,9 @@ static int client_node_demarshal_port_buffers(void *object, const struct pw_prot SPA_POD_Int(&n_buffers), NULL) < 0) return -EINVAL; + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + buffers = alloca(sizeof(struct spa_buffer*) * n_buffers); for (i = 0; i < n_buffers; i++) { struct spa_buffer *buf = buffers[i] = alloca(sizeof(struct spa_buffer)); @@ -1122,6 +1147,9 @@ static int client_node_demarshal_port_buffers(void *object, const struct pw_prot SPA_POD_Int(&buf->n_datas), NULL) < 0) return -EINVAL; + if (buf->n_datas > MAX_DATAS) + return -ENOSPC; + buf->datas = alloca(sizeof(struct spa_data) * buf->n_datas); for (j = 0; j < buf->n_datas; j++) { struct spa_data *d = &buf->datas[j]; diff --git a/src/modules/module-client-node/remote-node.c b/src/modules/module-client-node/remote-node.c index a7c8edbec..2dd087e38 100644 --- a/src/modules/module-client-node/remote-node.c +++ b/src/modules/module-client-node/remote-node.c @@ -41,7 +41,8 @@ #include "pipewire/extensions/protocol-native.h" #include "pipewire/extensions/client-node.h" -#define MAX_MIX 4096 +#define MAX_BUFFERS 64 +#define MAX_MIX 4096 PW_LOG_TOPIC_EXTERN(mod_topic); #define PW_LOG_TOPIC_DEFAULT mod_topic @@ -629,6 +630,9 @@ client_node_port_use_buffers(void *object, goto error_exit; } + if (n_buffers > MAX_BUFFERS) + return -ENOSPC; + prot = PW_MEMMAP_FLAG_READWRITE; /* clear previous buffers */ diff --git a/src/modules/module-protocol-native/protocol-native.c b/src/modules/module-protocol-native/protocol-native.c index 00cd971bd..9d7d186d5 100644 --- a/src/modules/module-protocol-native/protocol-native.c +++ b/src/modules/module-protocol-native/protocol-native.c @@ -34,6 +34,10 @@ #include "connection.h" +#define MAX_DICT 256 +#define MAX_PARAM_INFO 128 +#define MAX_PERMISSIONS 1024 + PW_LOG_TOPIC_EXTERN(mod_topic); #define PW_LOG_TOPIC_DEFAULT mod_topic @@ -175,6 +179,8 @@ do { \ (d)->items = NULL; \ if ((d)->n_items > 0) { \ uint32_t i; \ + if ((d)->n_items > MAX_DICT) \ + return -ENOSPC; \ (d)->items = alloca((d)->n_items * sizeof(struct spa_dict_item)); \ for (i = 0; i < (d)->n_items; i++) { \ if (parse_item(prs, (struct spa_dict_item *) &(d)->items[i]) < 0) \ @@ -216,6 +222,8 @@ do { \ params = NULL; \ if (n_params > 0) { \ uint32_t i; \ + if (n_params > MAX_PARAM_INFO) \ + return -ENOSPC; \ params = alloca(n_params * sizeof(struct spa_param_info)); \ for (i = 0; i < n_params; i++) { \ if (spa_pod_parser_get(prs, \ @@ -237,6 +245,8 @@ do { \ permissions = NULL; \ if (n_permissions > 0) { \ uint32_t i; \ + if (n_permissions > MAX_PERMISSIONS) \ + return -ENOSPC; \ permissions = alloca(n_permissions * sizeof(struct pw_permission)); \ for (i = 0; i < n_permissions; i++) { \ if (spa_pod_parser_get(prs, \ diff --git a/src/modules/module-session-manager/protocol-native.c b/src/modules/module-session-manager/protocol-native.c index 9ad65215b..36e5eede8 100644 --- a/src/modules/module-session-manager/protocol-native.c +++ b/src/modules/module-session-manager/protocol-native.c @@ -32,6 +32,10 @@ #include #include +#define MAX_DICT 256 +#define MAX_PARAMS 128 +#define MAX_PARAM_INFO 128 + static void push_dict(struct spa_pod_builder *b, const struct spa_dict *dict) { struct spa_pod_frame f; @@ -61,6 +65,8 @@ do { \ return -EINVAL; \ \ if ((dict)->n_items > 0) { \ + if ((dict)->n_items > MAX_DICT) \ + return -ENOSPC; \ (dict)->items = alloca((dict)->n_items * sizeof(struct spa_dict_item)); \ for (i = 0; i < (dict)->n_items; i++) { \ if (spa_pod_parser_get(p, \ @@ -100,6 +106,8 @@ do { \ return -EINVAL; \ \ if (*(n_params_p) > 0) { \ + if (*(n_params_p) > MAX_PARAM_INFO) \ + return -ENOSPC; \ *(params_p) = alloca(*(n_params_p) * sizeof(struct spa_param_info)); \ for (i = 0; i < *(n_params_p); i++) { \ if (spa_pod_parser_get(p, \ @@ -553,6 +561,8 @@ static int client_endpoint_demarshal_update(void *object, SPA_POD_Int(&n_params), NULL) < 0) return -EINVAL; + if (n_params > MAX_PARAMS) + return -ENOSPC; if (n_params > 0) params = alloca(n_params * sizeof(struct spa_pod *)); for (i = 0; i < n_params; i++) @@ -593,6 +603,8 @@ static int client_endpoint_demarshal_stream_update(void *object, SPA_POD_Int(&n_params), NULL) < 0) return -EINVAL; + if (n_params > MAX_PARAMS) + return -ENOSPC; if (n_params > 0) params = alloca(n_params * sizeof(struct spa_pod *)); for (i = 0; i < n_params; i++) @@ -867,6 +879,8 @@ static int client_session_demarshal_update(void *object, SPA_POD_Int(&n_params), NULL) < 0) return -EINVAL; + if (n_params > MAX_PARAMS) + return -ENOSPC; if (n_params > 0) params = alloca(n_params * sizeof(struct spa_pod *)); for (i = 0; i < n_params; i++) @@ -907,6 +921,8 @@ static int client_session_demarshal_link_update(void *object, SPA_POD_Int(&n_params), NULL) < 0) return -EINVAL; + if (n_params > MAX_PARAMS) + return -ENOSPC; if (n_params > 0) params = alloca(n_params * sizeof(struct spa_pod *)); for (i = 0; i < n_params; i++)