[pulseaudio-discuss] [PATCH v3 03/11] srbchannel: Introduce per-client SHM files

Ahmed S. Darwish darwish.07 at gmail.com
Sat Mar 12 22:53:34 UTC 2016


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



More information about the pulseaudio-discuss mailing list