gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/pulseaudio.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2017 Canonical Ltd 5 * 6 * This program is free software: you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 3 as 8 * published by the Free Software Foundation. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. If not, see <http://www.gnu.org/licenses/>. 17 * 18 */ 19 20 package builtin 21 22 import ( 23 "gitee.com/mysnapcore/mysnapd/interfaces" 24 "gitee.com/mysnapcore/mysnapd/interfaces/apparmor" 25 "gitee.com/mysnapcore/mysnapd/interfaces/seccomp" 26 "gitee.com/mysnapcore/mysnapd/interfaces/udev" 27 "gitee.com/mysnapcore/mysnapd/release" 28 "gitee.com/mysnapcore/mysnapd/snap" 29 ) 30 31 const pulseaudioSummary = `allows operating as or interacting with the pulseaudio service` 32 33 const pulseaudioBaseDeclarationSlots = ` 34 pulseaudio: 35 allow-installation: 36 slot-snap-type: 37 - app 38 - core 39 deny-connection: 40 on-classic: false 41 deny-auto-connection: true 42 ` 43 44 const pulseaudioConnectedPlugAppArmor = ` 45 # Allow communicating with pulseaudio service for playback and, on some 46 # distributions, recording. 47 /{run,dev}/shm/pulse-shm-* mrwk, 48 49 owner /{,var/}run/pulse/ r, 50 owner /{,var/}run/pulse/native rwk, 51 owner /{,var/}run/pulse/pid r, 52 owner /{,var/}run/user/[0-9]*/ r, 53 owner /{,var/}run/user/[0-9]*/pulse/ rw, 54 55 /run/udev/data/c116:[0-9]* r, 56 /run/udev/data/+sound:card[0-9]* r, 57 ` 58 59 const pulseaudioConnectedPlugAppArmorDesktop = ` 60 # Only on desktop do we need access to /etc/pulse for any PulseAudio client 61 # to read available client side configuration settings. On an Ubuntu Core 62 # device those things will be stored inside the snap directory. 63 /etc/pulse/ r, 64 /etc/pulse/** r, 65 owner @{HOME}/.pulse-cookie rk, 66 owner @{HOME}/.config/pulse/cookie rk, 67 owner /{,var/}run/user/*/pulse/ rwk, 68 owner /{,var/}run/user/*/pulse/native rwk, 69 owner /{,var/}run/user/*/pulse/pid r, 70 ` 71 72 const pulseaudioConnectedPlugSecComp = ` 73 shmctl 74 ` 75 76 const pulseaudioPermanentSlotAppArmor = ` 77 # When running PulseAudio in system mode it will switch to the at 78 # build time configured user/group on startup. 79 capability setuid, 80 capability setgid, 81 82 capability sys_nice, 83 capability sys_resource, 84 85 owner @{PROC}/@{pid}/exe r, 86 /etc/machine-id r, 87 88 # Audio related 89 @{PROC}/asound/devices r, 90 @{PROC}/asound/card** r, 91 92 # Should use the alsa interface instead 93 /dev/snd/pcm* rw, 94 /dev/snd/control* rw, 95 /dev/snd/timer r, 96 97 /sys/**/sound/** r, 98 99 # For udev 100 network netlink raw, 101 /sys/devices/virtual/dmi/id/sys_vendor r, 102 /sys/devices/virtual/dmi/id/bios_vendor r, 103 # FIXME: use udev queries to make this more specific 104 /run/udev/data/** r, 105 106 owner /{,var/}run/pulse/ rw, 107 owner /{,var/}run/pulse/** rwk, 108 109 # Shared memory based communication with clients 110 /{run,dev}/shm/pulse-shm-* mrwk, 111 112 /usr/share/applications/ r, 113 114 owner /run/pulse/native/ rwk, 115 owner /run/user/[0-9]*/ r, 116 owner /run/user/[0-9]*/pulse/ rw, 117 ` 118 119 const pulseaudioPermanentSlotSecComp = ` 120 # The following are needed for UNIX sockets 121 personality 122 setpriority 123 bind 124 listen 125 accept 126 accept4 127 shmctl 128 # Needed to set root as group for different state dirs 129 # pulseaudio creates on startup. 130 setgroups 131 setgroups32 132 # libudev 133 socket AF_NETLINK - NETLINK_KOBJECT_UEVENT 134 ` 135 136 type pulseAudioInterface struct{} 137 138 func (iface *pulseAudioInterface) Name() string { 139 return "pulseaudio" 140 } 141 142 func (iface *pulseAudioInterface) StaticInfo() interfaces.StaticInfo { 143 return interfaces.StaticInfo{ 144 Summary: pulseaudioSummary, 145 ImplicitOnClassic: true, 146 BaseDeclarationSlots: pulseaudioBaseDeclarationSlots, 147 } 148 } 149 150 func (iface *pulseAudioInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 151 spec.AddSnippet(pulseaudioConnectedPlugAppArmor) 152 if release.OnClassic { 153 spec.AddSnippet(pulseaudioConnectedPlugAppArmorDesktop) 154 } 155 return nil 156 } 157 158 func (iface *pulseAudioInterface) UDevPermanentSlot(spec *udev.Specification, slot *snap.SlotInfo) error { 159 spec.TagDevice(`KERNEL=="controlC[0-9]*"`) 160 spec.TagDevice(`KERNEL=="pcmC[0-9]*D[0-9]*[cp]"`) 161 spec.TagDevice(`KERNEL=="timer"`) 162 return nil 163 } 164 165 func (iface *pulseAudioInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error { 166 spec.AddSnippet(pulseaudioPermanentSlotAppArmor) 167 return nil 168 } 169 170 func (iface *pulseAudioInterface) SecCompConnectedPlug(spec *seccomp.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 171 spec.AddSnippet(pulseaudioConnectedPlugSecComp) 172 return nil 173 } 174 175 func (iface *pulseAudioInterface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error { 176 spec.AddSnippet(pulseaudioPermanentSlotSecComp) 177 return nil 178 } 179 180 func (iface *pulseAudioInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 181 return true 182 } 183 184 func init() { 185 registerIface(&pulseAudioInterface{}) 186 }