The PA daemon currently uses a single SHM file for all clients sending and receiving commands over the low-latency srbchannel mechanism. To avoid leaks between clients in that case, and to provide the necessary ground work later for sandboxing and memfds, create the srbchannel SHM files on a per-client basis. Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com> --- src/pulsecore/core.c | 10 ---------- src/pulsecore/core.h | 6 ++---- src/pulsecore/protocol-native.c | 28 +++++++++++++++++++++++++--- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c index 30dbde9..fe67109 100644 --- a/src/pulsecore/core.c +++ b/src/pulsecore/core.c @@ -126,11 +126,6 @@ pa_core* pa_core_new(pa_mainloop_api *m, bool shared, size_t shm_size) { c->shm_size = shm_size; pa_silence_cache_init(&c->silence_cache); - if (shared && !(c->rw_mempool = pa_mempool_new(shared, shm_size))) - pa_log_warn("Failed to allocate shared writable memory pool."); - if (c->rw_mempool) - pa_mempool_set_is_remote_writable(c->rw_mempool, true); - c->exit_event = NULL; c->scache_auto_unload_event = NULL; @@ -217,8 +212,6 @@ static void core_free(pa_object *o) { pa_assert(!c->default_sink); pa_silence_cache_done(&c->silence_cache); - if (c->rw_mempool) - pa_mempool_unref(c->rw_mempool); pa_mempool_unref(c->mempool); for (j = 0; j < PA_CORE_HOOK_MAX; j++) @@ -284,9 +277,6 @@ void pa_core_maybe_vacuum(pa_core *c) { } pa_mempool_vacuum(c->mempool); - - if (c->rw_mempool) - pa_mempool_vacuum(c->rw_mempool); } pa_time_event* pa_core_rttime_new(pa_core *c, pa_usec_t usec, pa_time_event_cb_t cb, void *userdata) { diff --git a/src/pulsecore/core.h b/src/pulsecore/core.h index 428689c..9f5c445 100644 --- a/src/pulsecore/core.h +++ b/src/pulsecore/core.h @@ -177,10 +177,8 @@ struct pa_core { PA_LLIST_HEAD(pa_subscription_event, subscription_event_queue); pa_subscription_event *subscription_event_last; - /* The mempool is used for data we write to, it's readonly for the client. - The rw_mempool is used for data writable by both server and client (and - can be NULL in some cases). */ - pa_mempool *mempool, *rw_mempool; + /* The mempool is used for data we write to, it's readonly for the client. */ + pa_mempool *mempool; /* Shared memory size, as specified either by daemon configuration * or PA daemon defaults (~ 64 MiB). */ diff --git a/src/pulsecore/protocol-native.c b/src/pulsecore/protocol-native.c index 145db04..82ea267 100644 --- a/src/pulsecore/protocol-native.c +++ b/src/pulsecore/protocol-native.c @@ -173,6 +173,12 @@ struct pa_native_connection { bool is_local:1; uint32_t version; pa_client *client; + /* R/W mempool, one per client connection, for srbchannel transport. + * Both server and client can write to this shm area. + * + * Note: This will be NULL if our connection with the client does + * not support srbchannels */ + pa_mempool *rw_mempool; pa_pstream *pstream; pa_pdispatch *pdispatch; pa_idxset *record_streams, *output_streams; @@ -1371,6 +1377,9 @@ static void native_connection_free(pa_object *o) { pa_pdispatch_unref(c->pdispatch); pa_pstream_unref(c->pstream); + if (c->rw_mempool) + pa_mempool_unref(c->rw_mempool); + pa_client_free(c->client); pa_xfree(c); @@ -2606,14 +2615,25 @@ static void setup_srbchannel(pa_native_connection *c) { return; } - if (!c->protocol->core->rw_mempool) { - pa_log_debug("Disabling srbchannel, reason: No rw memory pool"); + if (c->rw_mempool) { + pa_log_debug("Ignoring srbchannel setup, reason: received COMMAND_AUTH " + "more than once"); + return; + } + + if (!(c->rw_mempool = pa_mempool_new(true, c->protocol->core->shm_size))) { + pa_log_warn("Disabling srbchannel, reason: Failed to allocate shared " + "writable memory pool."); return; } + pa_mempool_set_is_remote_writable(c->rw_mempool, true); - srb = pa_srbchannel_new(c->protocol->core->mainloop, c->protocol->core->rw_mempool); + srb = pa_srbchannel_new(c->protocol->core->mainloop, c->rw_mempool); if (!srb) { pa_log_debug("Failed to create srbchannel"); + + pa_mempool_unref(c->rw_mempool); + c->rw_mempool = NULL; return; } pa_log_debug("Enabling srbchannel..."); @@ -5125,6 +5145,8 @@ void pa_native_protocol_connect(pa_native_protocol *p, pa_iochannel *io, pa_nati c->client->send_event = client_send_event_cb; c->client->userdata = c; + c->rw_mempool = NULL; + c->pstream = pa_pstream_new(p->core->mainloop, io, p->core->mempool); pa_pstream_set_receive_packet_callback(c->pstream, pstream_packet_callback, c); pa_pstream_set_receive_memblock_callback(c->pstream, pstream_memblock_callback, c); -- 2.7.2