security: add per-client operation count limit in PulseAudio protocol

There was no limit on pending operations per client. Commands like
SET_SINK_VOLUME each allocate an operation that persists until a
manager sync completes. A client flooding these commands can exhaust
server memory. Add a MAX_OPERATIONS (64) limit per client.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
Wim Taymans 2026-04-29 17:16:44 +02:00
parent f32295429f
commit 138e30df38
3 changed files with 8 additions and 0 deletions

View file

@ -80,6 +80,7 @@ struct client {
struct spa_list out_messages;
struct spa_list operations;
uint32_t n_operations;
struct spa_list pending_samples;

View file

@ -42,6 +42,7 @@
#define MAX_CLIENTS 64u
#define MAX_STREAMS 64u
#define MAX_OPERATIONS 64u
#define MODULE_INDEX_MASK 0xfffffffu
#define MODULE_FLAG (1u << 29)

View file

@ -8,6 +8,7 @@
#include <pipewire/log.h>
#include "client.h"
#include "defs.h"
#include "log.h"
#include "manager.h"
#include "operation.h"
@ -19,6 +20,9 @@ int operation_new_cb(struct client *client, uint32_t tag,
{
struct operation *o;
if (client->n_operations >= MAX_OPERATIONS)
return -ENOSPC;
if ((o = calloc(1, sizeof(*o))) == NULL)
return -errno;
@ -28,6 +32,7 @@ int operation_new_cb(struct client *client, uint32_t tag,
o->data = data;
spa_list_append(&client->operations, &o->link);
client->n_operations++;
pw_manager_sync(client->manager);
pw_log_debug("client %p [%s]: new operation tag:%u", client, client->name, tag);
@ -42,6 +47,7 @@ int operation_new(struct client *client, uint32_t tag)
void operation_free(struct operation *o)
{
o->client->n_operations--;
spa_list_remove(&o->link);
free(o);
}