modules: limit the max amount of items in the protocol

For now, put a limit on the amount of items we can send and receive
over the native protocol. A more complex way of allocating and freeing
can be implemented later when we really need to raise the limits.

Fixes #2070
This commit is contained in:
Wim Taymans 2022-01-28 15:55:44 +01:00
parent 92198e4d0d
commit ead827d6cb
6 changed files with 70 additions and 2 deletions

View file

@ -32,6 +32,9 @@
#include <pipewire/extensions/protocol-native.h>
#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, \

View file

@ -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,

View file

@ -33,6 +33,13 @@
#include <pipewire/extensions/protocol-native.h>
#include <pipewire/extensions/client-node.h>
#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(&params[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];

View file

@ -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 */

View file

@ -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, \

View file

@ -32,6 +32,10 @@
#include <pipewire/extensions/session-manager.h>
#include <pipewire/extensions/protocol-native.h>
#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++)