Join GitHub today
GitHub is home to over 20 million developers working together to host and review code, manage projects, and build software together.
interfaces/builtin: improve pulseaudio interface #1432
Conversation
and others
added some commits
May 24, 2016
|
whitelist this please |
zyga
reviewed
Jun 28, 2016
| +} | ||
| + | ||
| +func (iface *PulseAudioInterface) AutoConnect() bool { | ||
| + return false |
jhodapp
Jun 29, 2016
•
Not sure why it got changed (Simon did the interface changes) but it's fixed now. I'll double check that he didn't change this for a specific reason.
zyga
reviewed
Jun 28, 2016
| +setpriority | ||
| +setsockopt | ||
| +getsockname | ||
| +bind |
zyga
Jun 28, 2016
•
Contributor
Not 100% sure but don't we just want to make pulseaudio to use the network and network-bind slots?
jdstrand
Jun 29, 2016
Contributor
All of these I imagine are for the UNIX socket, not INET, so, no, let's leave this as is.
morphis
Jun 29, 2016
Contributor
@jhodapp Can you add a note that we're using them for UNIX sockets?
zyga
reviewed
Jun 28, 2016
| + | ||
| +# For udev | ||
| +network netlink raw, | ||
| +/sys/devices/virtual/dmi/id/sys_vendor r, |
zyga
Jun 28, 2016
Contributor
While something that pulse probably needs for valid reasons, we could move this to a dmi interface. Not sure.
morphis
Jun 29, 2016
Contributor
Unsure too, I would say we leave this for now and create a DMI interface if needed.
zyga
reviewed
Jun 28, 2016
| +capability sys_resource, | ||
| + | ||
| +@{PROC}/self/exe r, | ||
| +/etc/machine-id r, |
zyga
Jun 28, 2016
Contributor
Can we move this to the apparmor template instead? @jdstrand what do you think?
jdstrand
Jul 8, 2016
Contributor
Please remove /etc/machine-id here too-- it is part of the default policy now.
zyga
reviewed
Jun 28, 2016
| - name: "pulseaudio", | ||
| - connectedPlugAppArmor: pulseaudioConnectedPlugAppArmor, | ||
| - connectedPlugSecComp: pulseaudioConnectedPlugSecComp, | ||
| - reservedForOS: true, |
zyga
Jun 28, 2016
•
Contributor
Removing this reservedForOS will allow anyone to upload a snap with the pulseaudio slot. Can we please make sure that is flagging the snap for manual review in the store?
jdstrand
Jun 29, 2016
Contributor
Specifying slots in the yaml by default triggers a manual review, so this should be fine.
zyga
reviewed
Jun 28, 2016
| +`) | ||
| + | ||
| +var pulseaudioConnectedPlugAppArmorDesktop = []byte(` | ||
| +# Only on desktop we need access to /etc/pulse for any PulseAudio client |
zyga
Jun 28, 2016
Contributor
This requires more work but you can use release.OnClassic and construct the rules dynamically so that we don't hand out too many permissions.
jhodapp
Jun 29, 2016
I've got what I think is the right thing for this. Take a look and let me know if it's what you had in mind. I'm completely new to snaps, snap interfaces, etc - just an FYI.
|
Some good stuff there but I would encourage you to split classic and all-snap systems harder. We also want to ensure that pulseaudio automatically connects on classic (on all-snaps this is more of a topic to discuss but I don't see why not) so that we don't break existing systems. I'd like to see some more testing on this, perhaps we can snap some tools (paplay?) and write a spread test that installs it and ensures it is connected. We could even try to play some sound, ensuring that it doesn't crash. If you need help with any of that please let me know. What is our all-snap testing strategy? I think we could also use spread with an all-snap system and install pulseaudio along with a test snap and ensure that same dummy paplay thing works. |
zyga
added
the
Reviewed
label
Jun 28, 2016
jhodapp
commented
Jun 28, 2016
|
Thanks for the feedback @zyga. Simon wrote the interface part, so I'm going to defer to him to comment on those parts. |
jdstrand
reviewed
Jun 29, 2016
| -/etc/pulse/ r, | ||
| -/etc/pulse/* r, | ||
| +var pulseaudioConnectedPlugAppArmor = []byte(` | ||
| +capability dac_override, |
jdstrand
Jun 29, 2016
Contributor
What is this needed? This grants more access than we want to grant and I'd like to better understand why you added it.
morphis
Jun 29, 2016
Contributor
Pulseaudio tries to switch to a different user which is configured at compile time (root, root in our case). I wasn't sure if we want this left in or better disable the setuid/setgid call in the code.
morphis
Jun 29, 2016
Contributor
But to be honest, I can't remember right now why this was required for the plug side as setuid/setgid happens on the slot side.
jdstrand
reviewed
Jun 29, 2016
| +var pulseaudioConnectedPlugAppArmor = []byte(` | ||
| +capability dac_override, | ||
| + | ||
| +/etc/machine-id r, |
jdstrand
Jun 29, 2016
Contributor
This is currently allowed in 'abstractions/dbus-session-strict'. On touch we specifically disabled the DBus socket and only allowed apps to connect via the native socket. Is this changing or is pulseaudio using /etc/machine-id for something unrelated?
morphis
Jun 29, 2016
Contributor
It uses machine-id in various places to name its sockets. On the client side its using this to build the correct socket name which it will then access.
jdstrand
reviewed
Jun 29, 2016
| -owner /{,var/}run/user/*/pulse/ r, | ||
| + | ||
| +# FIXME Desktop-only | ||
| +owner /{,var/}run/user/*/pulse/ rwk, | ||
| owner /{,var/}run/user/*/pulse/native rwk, |
jdstrand
Jun 29, 2016
Contributor
This is easy enough to do programmatically-- use release.OnClassic strategically to add these.
morphis
Jun 29, 2016
Contributor
@jhodapp Can you split those two lines out and combine with the snippet depending on if release.OnClassic is set?
jdstrand
reviewed
Jun 29, 2016
| -const pulseaudioConnectedPlugSecComp = ` | ||
| +# Running as system instance | ||
| +owner /{,var/}run/pulse rwk, |
jdstrand
Jun 29, 2016
Contributor
This is a weird access (why does the client create the pulse directory?) and you are also missing the trailing '/'. I think you want this instead:
owner /{,var/}run/pulse/ r,
|
@zyga We have a pulseaudio snap which includes paplay/pactl at https://code.launchpad.net/~morphis/snappy-hwe-snaps/+git/pulseaudio/+ref/add-initial-packaging which can be used for testing. Adding a spread test would be a good thing but would require more tíme than we currently have for this. @jhodapp can you have a quick look what it would mean to come up with a spread test for this? @zyga Does spread require the snap being published in the store? |
added some commits
Jun 29, 2016
|
@morphis As for spread tests, I don't think this is a strict requirement, we have some demo snaps that we build during the testing process. Still I think it is fine to have an array of snaps in the store that are only there for testing. Use your best judgment to decide. As an alternative to a spread test can we please have a manual test case so that we can check this once in a while? @fgimenez and @elopio will advise on how to express that. Thanks for the big update, I'll re-review it soon. |
jhodapp
commented
Jun 30, 2016
|
I don't understand why the Travis CI build keeps failing now. I don't see a specific error from the code but I do see something that looks like an infrastructure timeout or related. |
|
@jhodapp There was a bug in master introduced by a change in spread (we moved from sh to bash). Can you please merge master and re-push? |
niemeyer
changed the title from
Pulse audio tests
to
interfaces/builtin: improve pulseaudio interface
Jul 4, 2016
|
Can one of the admins verify this patch? |
|
Can one of the admins verify this patch? |
added some commits
Jul 6, 2016
|
Can one of the admins verify this patch? |
|
Can one of the admins verify this patch? |
|
Can one of the admins verify this patch? |
jdstrand
reviewed
Jul 8, 2016
| +var pulseaudioConnectedPlugAppArmor = []byte(` | ||
| +capability dac_override, | ||
| + | ||
| +/etc/machine-id r, |
jdstrand
reviewed
Jul 8, 2016
| ) | ||
| -const pulseaudioConnectedPlugAppArmor = ` | ||
| +var pulseaudioConnectedPlugAppArmor = []byte(` | ||
| +capability dac_override, |
jdstrand
Jul 8, 2016
Contributor
Please remove this. From @morphis "But to be honest, I can't remember right now why this was required for the plug side as setuid/setgid happens on the slot side." The connected plug should not need elevated privileges to work with pulseaudio, which this capability rule grants. If after removing it you still need it, please investigate way and adjust the slot snap to not require the plug snap to need this.
jdstrand
reviewed
Jul 8, 2016
| +var pulseaudioConnectedPlugAppArmorDesktop = []byte(` | ||
| +# Only on desktop do we need access to /etc/pulse for any PulseAudio client | ||
| +# to read available client side configuration settings. On an Ubuntu Core | ||
| +# device those things will be stored inside the snap directory. | ||
| /etc/pulse/ r, | ||
| /etc/pulse/* r, |
jdstrand
Jul 8, 2016
Contributor
In addition to these desktop-only accesses, shouldn't we also add these for the pulse cookie (from Touch policy):
owner @{HOME}/.pulse-cookie rk,
owner @{HOME}/.config/pulse/cookie rk,
and when are these needed (if ever):
owner @{HOME}/.pulse/ r,
owner @{HOME}/.pulse/* rk,
jdstrand
reviewed
Jul 8, 2016
| + | ||
| +/{run,dev}/shm/pulse-shm-* rwk, | ||
| + | ||
| +# Running as system instance |
jdstrand
Jul 8, 2016
Contributor
I think this comment is not quite right as it applies to both when running as a snap and when running on the system, no?
jdstrand
reviewed
Jul 8, 2016
| +capability sys_nice, | ||
| +capability sys_resource, | ||
| + | ||
| +@{PROC}/self/exe r, |
jdstrand
Jul 8, 2016
Contributor
This rule is likely not correct since self is a symlink. Can you try removing this rule? If you get a denial after removing it, use this instead: owner @{PROC}/@{pid}/exe r,
jdstrand
reviewed
Jul 8, 2016
| +network netlink raw, | ||
| +/sys/devices/virtual/dmi/id/sys_vendor r, | ||
| +/sys/devices/virtual/dmi/id/bios_vendor r, | ||
| +/run/udev/data/** r, |
jdstrand
Jul 8, 2016
•
Contributor
I'll broken record this one-- we should use udev queries to obtain a specific list of accesses in /run/udev/data/**. For now, can you add a #FIXME: use udev queries to make this more specific?
jdstrand
reviewed
Jul 8, 2016
| +owner /{,var/}run/pulse/.config/pulse/ rwk, | ||
| + | ||
| +# Shared memory based communication with clients | ||
| +/{run,dev}/shm/pulse-shm-* rwkcix, |
jdstrand
Jul 8, 2016
Contributor
'c' shouldn't be used and is covered by 'w'. You also shouldn't granted e'x'ec here either. Please use: /{run,dev}/shm/pulse-shm-* rwk, instead.
jdstrand
reviewed
Jul 8, 2016
| +owner /{,var/}run/pulse/native rwk, | ||
| +owner /{,var/}run/pulse/pid rwk, | ||
| +owner /{,var/}run/pulse/.config/ rwk, | ||
| +owner /{,var/}run/pulse/.config/pulse/ rwk, |
jdstrand
Jul 8, 2016
Contributor
I think you should simplify this to simply be:
owner /{,var/}run/pulse/ rw,
owner /{,var/}run/pulse/** rwk,
jdstrand
reviewed
Jul 8, 2016
| + | ||
| +# Shared memory based communication with clients | ||
| +/{run,dev}/shm/pulse-shm-* rwkcix, | ||
| +owner /{,var/}run/pulse/.config/pulse/cookie rwk, |
jdstrand
Jul 8, 2016
Contributor
This can be removed if you take my simplified rules suggestion, above.
|
Please adjust the policy as I suggested just now. All other policy LGTM. Thanks! |
jdstrand
reviewed
Jul 20, 2016
| ) | ||
| -const pulseaudioConnectedPlugAppArmor = ` | ||
| +var pulseaudioConnectedPlugAppArmor = []byte(` | ||
| +/{run,dev}/shm/pulse-shm-* rwk, |
jdstrand
Jul 20, 2016
Contributor
On the plugs side, shouldn't we use this instead: owner /{run,dev}/shm/pulse-shm-* rwk, ?
jdstrand
reviewed
Jul 20, 2016
| + b := bytes.NewBuffer(pulseaudioConnectedPlugAppArmorDesktop) | ||
| + // Add these bytes to the connected plug apparmor rules | ||
| + b.Write([]byte("owner /{,var/}run/user/*/pulse/ rwk,\n")) | ||
| + b.Write([]byte("owner /{,var/}run/user/*/pulse/native rwk,\n")) |
jdstrand
Jul 20, 2016
Contributor
Wouldn't this be better so concatenate pulseaudioConnectedPlugAppArmor and pulseaudioConnectedPlugAppArmorDesktop when OnClassic and continue to use only pulseaudioConnectedPlugAppArmor when not?
morphis
Jul 21, 2016
Contributor
@jdstrand Why not, that would match what we do for other interfaces.
jdstrand
Jul 21, 2016
Contributor
The difference with other interfaces is that they are different rules (if not, then that was a mistake). This is very clearly "always use these few rules and if on classic, also add these others", so the code should reflect that by putting the "always use these few rules" in pulseaudioConnectedPlugAppArmor and then the desktop only ones in pulseaudioConnectedPlugAppArmorDesktop. As it stands there is a small maintenance and auditibility issue since the /{,var/}run/user/*/pulse/ rules are duplicated in two quite different places.
jdstrand
reviewed
Jul 27, 2016
| + b1.Write(b0.Bytes()) | ||
| + // Add these bytes to the connected plug apparmor rules | ||
| + b1.Write([]byte("owner /{,var/}run/user/*/pulse/ rwk,\n")) | ||
| + b1.Write([]byte("owner /{,var/}run/user/*/pulse/native rwk,\n")) |
jdstrand
Jul 27, 2016
Contributor
Please move these two apparmor rules to the definition of pulseaudioConnectedPlugAppArmorDesktop that starts at line 36 to complete what I suggested (sorry if that wasn't clear before).
Once done, LGTM and +1.
added some commits
Jul 27, 2016
|
The security policy looks fine now. Thanks! Assuming that the checks pass and Jim is happy with his testing, +1 |
jhodapp
commented
Jul 28, 2016
|
This is ready for final review by @zyga. |
|
Thank you for contributing this improvement. I'm sorry I took forever to review it. LGTM |
|
Hmm, the spread test failure looks genuine. Let me have a look |
jhodapp
commented
Jul 29, 2016
|
@zyga any update on why the spread test failure is happening? I did not get any test failures when running the local check. |
morphis
reviewed
Aug 1, 2016
| + | ||
| +func (iface *PulseAudioInterface) PermanentPlugSnippet(plug *interfaces.Plug, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
| + switch securitySystem { | ||
| + case interfaces.SecurityDBus, interfaces.SecurityAppArmor, interfaces.SecuritySecComp, interfaces.SecurityUDev: |
morphis
reviewed
Aug 1, 2016
| + } | ||
| + case interfaces.SecuritySecComp: | ||
| + return pulseaudioConnectedPlugSecComp, nil | ||
| + case interfaces.SecurityDBus, interfaces.SecurityUDev: |
morphis
reviewed
Aug 1, 2016
| + return pulseaudioPermanentSlotAppArmor, nil | ||
| + case interfaces.SecuritySecComp: | ||
| + return pulseaudioPermanentSlotSecComp, nil | ||
| + case interfaces.SecurityDBus, interfaces.SecurityUDev: |
morphis
reviewed
Aug 1, 2016
| + | ||
| +func (iface *PulseAudioInterface) ConnectedSlotSnippet(plug *interfaces.Plug, slot *interfaces.Slot, securitySystem interfaces.SecuritySystem) ([]byte, error) { | ||
| + switch securitySystem { | ||
| + case interfaces.SecurityDBus, interfaces.SecurityAppArmor, interfaces.SecuritySecComp, interfaces.SecurityUDev: |
morphis
reviewed
Aug 1, 2016
| + snippet, err = s.iface.PermanentSlotSnippet(s.slot, interfaces.SecurityUDev) | ||
| + c.Assert(err, IsNil) | ||
| + c.Assert(snippet, IsNil) | ||
| + snippet, err = s.iface.ConnectedPlugSnippet(s.plug, s.slot, interfaces.SecurityDBus) |
morphis
reviewed
Aug 1, 2016
| + c.Assert(err, Equals, interfaces.ErrUnknownSecurity) | ||
| + c.Assert(snippet, IsNil) | ||
| + snippet, err = s.iface.ConnectedSlotSnippet(s.plug, s.slot, "foo") | ||
| + c.Assert(err, Equals, interfaces.ErrUnknownSecurity) |
|
@jhodapp The reason why the CI is failing is because the interface does not support the recently added MountSecurity subsystem. Its pretty clear in what it says: error: cannot perform the following tasks:
I've added a comment at the different places where you need to add interfaces.MountSecurity. @jhodapp Also are you sure you executed the spread tests locally? If you just run run-checks it will not execute them by default unless you specify --spread |
jhodapp
commented
Aug 1, 2016
|
@morphis Are you sure that's what is required, or perhaps named something else? I see this both locally and while running with Travis here: "interfaces/builtin/pulseaudio.go:123: undefined: interfaces.MountSecurity" |
added some commits
Aug 1, 2016
|
@zyga Can you have a final look and merge this? |
jhodapp
commented
Aug 3, 2016
|
@niemeyer just a reminder to take a look at this PR today if you can, approve if happy and merge. |
jhodapp commentedJun 28, 2016
•
Edited 1 time
-
jhodapp
Jun 28, 2016
Add more complex PulseAudio interface, also add PulseAudio interface unit tests.