[pulseaudio-discuss] [PATCH 02/11] pulsecore: srbchannel: Introduce per-client SHM files

Ahmed S. Darwish darwish.07 at gmail.com
Sun Sep 20 14:28:30 PDT 2015


The PA daemon currently uses a server-wide SHM file for all clients
sending and receiving commands using the srbchannel.

To protect the clients from each other, and to provide the necessary
groundwork later for policy and sandboxing, create the srbchannel SHM
files on a per-client basis.

Signed-off-by: Ahmed S. Darwish <darwish.07 at gmail.com>
---
 src/pulsecore/client.c          |  5 +++++
 src/pulsecore/client.h          |  7 +++++++
 src/pulsecore/core.c            | 15 +++++----------
 src/pulsecore/core.h            |  6 ++----
 src/pulsecore/protocol-native.c | 16 ++++++++++++----
 5 files changed, 31 insertions(+), 18 deletions(-)

diff --git a/src/pulsecore/client.c b/src/pulsecore/client.c
index 003bcf8..5d60ad6 100644
--- a/src/pulsecore/client.c
+++ b/src/pulsecore/client.c
@@ -69,6 +69,8 @@ pa_client *pa_client_new(pa_core *core, pa_client_new_data *data) {
     c->sink_inputs = pa_idxset_new(NULL, NULL);
     c->source_outputs = pa_idxset_new(NULL, NULL);
 
+    c->rw_mempool = NULL;
+
     c->userdata = NULL;
     c->kill = NULL;
     c->send_event = NULL;
@@ -105,6 +107,9 @@ void pa_client_free(pa_client *c) {
     pa_assert(pa_idxset_isempty(c->source_outputs));
     pa_idxset_free(c->source_outputs, NULL);
 
+    if (c->rw_mempool)
+        pa_mempool_free(c->rw_mempool);
+
     pa_proplist_free(c->proplist);
     pa_xfree(c->driver);
     pa_xfree(c);
diff --git a/src/pulsecore/client.h b/src/pulsecore/client.h
index cd55348..67337a4 100644
--- a/src/pulsecore/client.h
+++ b/src/pulsecore/client.h
@@ -43,6 +43,13 @@ struct pa_client {
     pa_idxset *sink_inputs;
     pa_idxset *source_outputs;
 
+    /* This is the per-client read/write memory pool used for srbchannel
+     * support. Both server and client can write to this.
+     *
+     * This can be NULL if our connection with the client does not
+     * support srbchannel communication. */
+    pa_mempool *rw_mempool;
+
     void *userdata;
 
     void (*kill)(pa_client *c);
diff --git a/src/pulsecore/core.c b/src/pulsecore/core.c
index d198e48..546df44 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_free(c->rw_mempool);
     pa_mempool_free(c->mempool);
 
     for (j = 0; j < PA_CORE_HOOK_MAX; j++)
@@ -261,6 +254,8 @@ int pa_core_exit(pa_core *c, bool force, int retval) {
 }
 
 void pa_core_maybe_vacuum(pa_core *c) {
+    pa_client *client;
+    uint32_t idx;
     pa_assert(c);
 
     if (pa_idxset_isempty(c->sink_inputs) && pa_idxset_isempty(c->source_outputs)) {
@@ -268,7 +263,6 @@ void pa_core_maybe_vacuum(pa_core *c) {
     } else {
         pa_sink *si;
         pa_source *so;
-        uint32_t idx;
 
         idx = 0;
         PA_IDXSET_FOREACH(si, c->sinks, idx)
@@ -285,8 +279,9 @@ void pa_core_maybe_vacuum(pa_core *c) {
 
     pa_mempool_vacuum(c->mempool);
 
-    if (c->rw_mempool)
-        pa_mempool_vacuum(c->rw_mempool);
+    PA_IDXSET_FOREACH(client, c->clients, idx)
+        if (client->rw_mempool)
+            pa_mempool_vacuum(client->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 29680cb..fe2d9b6 100644
--- a/src/pulsecore/core.h
+++ b/src/pulsecore/core.h
@@ -178,10 +178,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 ec223be..5a062a6 100644
--- a/src/pulsecore/protocol-native.c
+++ b/src/pulsecore/protocol-native.c
@@ -2585,6 +2585,7 @@ static void command_exit(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_ta
 }
 
 static void setup_srbchannel(pa_native_connection *c) {
+    pa_mempool *rw_mempool = NULL;
     pa_srbchannel_template srbt;
     pa_srbchannel *srb;
     pa_memchunk mc;
@@ -2606,15 +2607,17 @@ 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 (!(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(rw_mempool, true);
 
-    srb = pa_srbchannel_new(c->protocol->core->mainloop, c->protocol->core->rw_mempool);
+    srb = pa_srbchannel_new(c->protocol->core->mainloop, rw_mempool);
     if (!srb) {
         pa_log_debug("Failed to create srbchannel");
-        return;
+        goto free_rw_mempool;
     }
     pa_log_debug("Enabling srbchannel...");
     pa_srbchannel_export(srb, &srbt);
@@ -2633,7 +2636,12 @@ static void setup_srbchannel(pa_native_connection *c) {
     mc.length = pa_memblock_get_length(srbt.memblock);
     pa_pstream_send_memblock(c->pstream, 0, 0, 0, &mc);
 
+    c->client->rw_mempool = rw_mempool;
     c->srbpending = srb;
+    return;
+
+free_rw_mempool:
+    pa_mempool_free(rw_mempool);
 }
 
 static void command_enable_srbchannel(pa_pdispatch *pd, uint32_t command, uint32_t tag, pa_tagstruct *t, void *userdata) {

-- 
Darwish
http://darwish.chasingpointers.com


More information about the pulseaudio-discuss mailing list