Merge ~ubuntu-audio-dev/pulseaudio:classic-snap-support into ~ubuntu-audio-dev/pulseaudio:ubuntu

Proposed by James Henstridge
Status: Merged
Merged at revision: f05181660af504509d841a6a5a5d8acb965a5c44
Proposed branch: ~ubuntu-audio-dev/pulseaudio:classic-snap-support
Merge into: ~ubuntu-audio-dev/pulseaudio:ubuntu
Diff against target: 163 lines (+62/-19)
2 files modified
debian/changelog (+6/-1)
debian/patches/0700-modules-add-snappy-policy-module.patch (+56/-18)
Reviewer Review Type Date Requested Status
Ubuntu Audio Development Team Pending
Review via email: mp+353214@code.launchpad.net

Commit message

debian/patches: grant classic snaps access to microphone.

Description of the change

The 1:12.2-0ubuntu2 release broke recording support for classic snaps. These snaps have an AppArmor label, but won't necessarily have the relevant Pulse Audio interfaces plugged: they are just expected to have access by default.

This can be demonstrated with a command like the following:

    aa-exec -p snap.skype.skype /usr/bin/parecord foo.wav

Without the changes in this branch, this gives an "access denied" error. With them, it successfully records audio to "foo.wav".

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
diff --git a/debian/changelog b/debian/changelog
index 9c2fe54..3d85ef7 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,10 +1,15 @@
1pulseaudio (1:12.2-0ubuntu3) UNRELEASED; urgency=medium1pulseaudio (1:12.2-0ubuntu3) cosmic; urgency=medium
22
3 [ Ken VanDine ]
3 * Update patch tags with more detailed descriptions and a note about 4 * Update patch tags with more detailed descriptions and a note about
4 not forwarding upstream:5 not forwarding upstream:
5 - 0700-modules-add-snappy-policy-module.patch6 - 0700-modules-add-snappy-policy-module.patch
6 - 0701-enable-snap-policy-module.patch7 - 0701-enable-snap-policy-module.patch
78
9 [ James Henstridge ]
10 * 0700-modules-add-snappy-policy-module.patch: grant recording access
11 to snaps with classic confinement. (LP: #1787324)
12
8 -- Ken VanDine <ken.vandine@canonical.com> Mon, 13 Aug 2018 10:11:10 -040013 -- Ken VanDine <ken.vandine@canonical.com> Mon, 13 Aug 2018 10:11:10 -0400
914
10pulseaudio (1:12.2-0ubuntu2) cosmic; urgency=medium15pulseaudio (1:12.2-0ubuntu2) cosmic; urgency=medium
diff --git a/debian/patches/0700-modules-add-snappy-policy-module.patch b/debian/patches/0700-modules-add-snappy-policy-module.patch
index 9d66510..96f62f7 100644
--- a/debian/patches/0700-modules-add-snappy-policy-module.patch
+++ b/debian/patches/0700-modules-add-snappy-policy-module.patch
@@ -1,18 +1,19 @@
1From: James Henstridge <james.henstridge@canonical.com>1From: James Henstridge <james.henstridge@canonical.com>
2Date: Tue, 7 Aug 2018 12:40:59 +08002Date: Tue, 7 Aug 2018 12:40:59 +0800
3Subject: [PATCH] modules: add snap policy module3Subject: [PATCH] modules: add snap policy module
4Co-authored-by: Simon Fels <simon.fels@canonical.com>4
5Forwarded: not-needed5Forwarded: not-needed
66
7This patch allows pulseaudio to limit audio recording to snaps with 7This patch allows pulseaudio to limit audio recording to snaps with
8the audio-recording interface connected. We will not pursue upstreaming8the audio-recording interface connected. We will not pursue upstreaming
9this patch as the longer term solution will probably use PipeWire. 9this patch as the longer term solution will probably use PipeWire.
1010
11Co-authored-by: Simon Fels <simon.fels@canonical.com>
11---12---
12 configure.ac | 17 ++13 configure.ac | 17 ++
13 src/Makefile.am | 13 ++14 src/Makefile.am | 13 ++
14 src/modules/module-snap-policy.c | 347 +++++++++++++++++++++++++++++++++++++++15 src/modules/module-snap-policy.c | 384 +++++++++++++++++++++++++++++++++++++++
15 3 files changed, 377 insertions(+)16 3 files changed, 414 insertions(+)
16 create mode 100644 src/modules/module-snap-policy.c17 create mode 100644 src/modules/module-snap-policy.c
1718
18diff --git a/configure.ac b/configure.ac19diff --git a/configure.ac b/configure.ac
@@ -90,10 +91,10 @@ index d623d0a..16b4d5d 100644
90 module_rtp_send_la_LDFLAGS = $(MODULE_LDFLAGS)91 module_rtp_send_la_LDFLAGS = $(MODULE_LDFLAGS)
91diff --git a/src/modules/module-snap-policy.c b/src/modules/module-snap-policy.c92diff --git a/src/modules/module-snap-policy.c b/src/modules/module-snap-policy.c
92new file mode 10064493new file mode 100644
93index 0000000..866047694index 0000000..0a1f5f4
94--- /dev/null95--- /dev/null
95+++ b/src/modules/module-snap-policy.c96+++ b/src/modules/module-snap-policy.c
96@@ -0,0 +1,347 @@97@@ -0,0 +1,384 @@
97+/***98+/***
98+ This file is part of PulseAudio.99+ This file is part of PulseAudio.
99+100+
@@ -171,18 +172,28 @@ index 0000000..8660476
171+172+
172+/* ---- Code running in glib thread ---- */173+/* ---- Code running in glib thread ---- */
173+174+
174+static void check_interfaces_finish(GObject *source_object,175+static void complete_check_access(struct per_client *pc, bool grant_access)
176+{
177+ struct userdata *u = pc->userdata;
178+
179+ pa_mutex_lock(u->mutex);
180+ pc->grant_access = grant_access;
181+ pc->completed = true;
182+ pa_asyncq_push(u->results, pc, true);
183+ pa_mutex_unlock(u->mutex);
184+}
185+
186+static void get_interfaces_finished(GObject *source_object,
175+ GAsyncResult *result,187+ GAsyncResult *result,
176+ gpointer user_data)188+ gpointer user_data)
177+{189+{
178+ struct per_client *pc = user_data;190+ struct per_client *pc = user_data;
179+ struct userdata *u = pc->userdata;191+ struct userdata *u = pc->userdata;
192+ bool grant_access = false;
180+ g_autoptr(GError) error = NULL;193+ g_autoptr(GError) error = NULL;
181+ g_autoptr(GPtrArray) plugs = NULL;194+ g_autoptr(GPtrArray) plugs = NULL;
182+ unsigned i;195+ unsigned i;
183+196+
184+ pa_mutex_lock(u->mutex);
185+
186+ if (!snapd_client_get_interfaces_finish(u->snapd, result, &plugs, NULL, &error)) {197+ if (!snapd_client_get_interfaces_finish(u->snapd, result, &plugs, NULL, &error)) {
187+ pa_log_warn("snapd_client_get_interfaces failed: %s", error->message);198+ pa_log_warn("snapd_client_get_interfaces failed: %s", error->message);
188+ goto end;199+ goto end;
@@ -200,24 +211,51 @@ index 0000000..8660476
200+ continue;211+ continue;
201+ }212+ }
202+ if (!strcmp(iface, "pulseaudio") || !strcmp(iface, "audio-record")) {213+ if (!strcmp(iface, "pulseaudio") || !strcmp(iface, "audio-record")) {
203+ pc->grant_access = true;214+ grant_access = true;
204+ break;215+ break;
205+ }216+ }
206+ }217+ }
207+218+
208+end:219+end:
209+ pc->completed = true;220+ complete_check_access(pc, grant_access);
210+ pa_asyncq_push(u->results, pc, true);
211+ pa_mutex_unlock(u->mutex);
212+}221+}
213+222+
214+static gboolean check_interfaces(void *data)223+static void get_snap_finished(GObject *source_object,
224+ GAsyncResult *result,
225+ gpointer user_data)
215+{226+{
216+ struct per_client *pc = data;227+ struct per_client *pc = user_data;
217+ struct userdata *u = pc->userdata;228+ struct userdata *u = pc->userdata;
229+ g_autoptr(GError) error = NULL;
230+ g_autoptr(SnapdSnap) snap = NULL;
231+
232+ snap = snapd_client_list_one_finish(u->snapd, result, &error);
233+ if (!snap) {
234+ pa_log_warn("snapd_client_get_snap failed: %s", error->message);
235+ complete_check_access(pc, false);
236+ return;
237+ }
238+
239+ /* Snaps using classic confinement are granted access */
240+ if (snapd_snap_get_confinement(snap) == SNAPD_CONFINEMENT_CLASSIC) {
241+ complete_check_access(pc, true);
242+ return;
243+ }
218+244+
245+ /* We have a non-classic snap, we need to check its connected
246+ * interfaces */
219+ snapd_client_get_interfaces_async(u->snapd, u->cancellable,247+ snapd_client_get_interfaces_async(u->snapd, u->cancellable,
220+ check_interfaces_finish, pc);248+ get_interfaces_finished, pc);
249+}
250+
251+
252+static gboolean check_access(void *data)
253+{
254+ struct per_client *pc = data;
255+ struct userdata *u = pc->userdata;
256+
257+ snapd_client_list_one_async(u->snapd, pc->snap_name, u->cancellable,
258+ get_snap_finished, pc);
221+ return G_SOURCE_REMOVE;259+ return G_SOURCE_REMOVE;
222+}260+}
223+261+
@@ -351,7 +389,7 @@ index 0000000..8660476
351+ pa_dynarray_append(pc->pending_requests, d);389+ pa_dynarray_append(pc->pending_requests, d);
352+ pa_hashmap_put(u->clients, (void *) (size_t) d->client_index, pc);390+ pa_hashmap_put(u->clients, (void *) (size_t) d->client_index, pc);
353+ pa_log_info("Checking access for client %d (%s)", pc->index, pc->snap_name);391+ pa_log_info("Checking access for client %d (%s)", pc->index, pc->snap_name);
354+ g_main_context_invoke(u->main_context, check_interfaces, pc);392+ g_main_context_invoke(u->main_context, check_access, pc);
355+393+
356+ result = PA_HOOK_CANCEL;394+ result = PA_HOOK_CANCEL;
357+395+

Subscribers

People subscribed via source and target branches