gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/browser_support.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 "fmt" 24 25 "gitee.com/mysnapcore/mysnapd/interfaces" 26 "gitee.com/mysnapcore/mysnapd/interfaces/apparmor" 27 "gitee.com/mysnapcore/mysnapd/interfaces/seccomp" 28 "gitee.com/mysnapcore/mysnapd/snap" 29 ) 30 31 const browserSupportSummary = `allows access to various APIs needed by modern web browsers` 32 33 const browserSupportBaseDeclarationSlots = ` 34 browser-support: 35 allow-installation: 36 slot-snap-type: 37 - core 38 deny-connection: 39 plug-attributes: 40 allow-sandbox: true 41 deny-auto-connection: 42 plug-attributes: 43 allow-sandbox: true 44 ` 45 46 const browserSupportConnectedPlugAppArmor = ` 47 # Description: Can access various APIs needed by modern browsers (eg, Google 48 # Chrome/Chromium and Mozilla) and file paths they expect. This interface is 49 # transitional and is only in place while upstream's work to change their paths 50 # and snappy is updated to properly mediate the APIs. 51 52 # This allows raising the OOM score of other processes owned by the user. 53 owner @{PROC}/@{pid}/oom_score_adj rw, 54 55 # Chrome/Chromium should be fixed to honor TMPDIR or the snap packaging 56 # adjusted to use LD_PRELOAD technique from LP: #1577514 57 /var/tmp/ r, 58 owner /var/tmp/etilqs_* rw, 59 60 # Chrome/Chromium should be modified to use snap.$SNAP_INSTANCE_NAME.* or 61 # the snap packaging adjusted to use LD_PRELOAD technique from LP: #1577514 62 owner /{dev,run}/shm/{,.}org.chromium.* mrw, 63 owner /{dev,run}/shm/{,.}com.google.Chrome.* mrw, 64 owner /{dev,run}/shm/{,.}com.microsoft.Edge.* mrw, 65 owner /{dev,run}/shm/.io.nwjs.* mrw, 66 67 # Chrome's Singleton API sometimes causes an ouid/fsuid mismatch denial, so 68 # for now, allow non-owner read on the singleton socket (LP: #1731012). See 69 # https://forum.snapcraft.io/t/electron-snap-killed-when-using-app-makesingleinstance-api/2667/20 70 # parallel-installs: $XDG_RUNTIME_DIR is not remapped, need to use SNAP_INSTANCE_NAME 71 /run/user/[0-9]*/snap.@{SNAP_INSTANCE_NAME}/{,.}org.chromium.*/SS r, 72 /run/user/[0-9]*/snap.@{SNAP_INSTANCE_NAME}/{,.}com.google.Chrome.*/SS r, 73 /run/user/[0-9]*/snap.@{SNAP_INSTANCE_NAME}/{,.}com.microsoft.Edge.*/SS r, 74 75 # Allow access to Jupyter notebooks. 76 # This is temporary and will be reverted once LP: #1959417 is fixed upstream. 77 owner @{HOME}/.local/share/jupyter/** rw, 78 79 # Allow reading platform files 80 /run/udev/data/+platform:* r, 81 82 # miscellaneous accesses 83 @{PROC}/vmstat r, 84 85 # Chromium content api sometimes queries about huge pages. Allow status of 86 # hugepages and transparent_hugepage, but not the pages themselves. 87 /sys/kernel/mm/{hugepages,transparent_hugepage}/{,**} r, 88 89 # Chromium content api in gnome-shell reads this 90 /etc/opt/chrome/{,**} r, 91 /etc/chromium/{,**} r, 92 93 # Chrome/Chromium should be adjusted to not use gconf. It is only used with 94 # legacy systems that don't have snapd 95 deny dbus (send) 96 bus=session 97 interface="org.gnome.GConf.Server", 98 99 # webbrowser-app/webapp-container tries to read this file to determine if it is 100 # confined or not, so explicitly deny to avoid noise in the logs. 101 deny @{PROC}/@{pid}/attr/{,apparmor/}current r, 102 103 # This is an information leak but disallowing it leads to developer confusion 104 # when using the chromium content api file chooser due to a (harmless) glib 105 # warning and the noisy AppArmor denial. 106 owner @{PROC}/@{pid}/mounts r, 107 owner @{PROC}/@{pid}/mountinfo r, 108 109 # Since snapd still uses SECCOMP_RET_KILL, we have added a workaround rule to 110 # allow mknod on character devices since chromium unconditionally performs 111 # a mknod() to create the /dev/nvidiactl device, regardless of if it exists or 112 # not or if the process has CAP_MKNOD or not. Since we don't want to actually 113 # grant the ability to create character devices, explicitly deny the 114 # capability. When snapd uses SECCOMP_RET_ERRNO, we can remove this rule. 115 # https://forum.snapcraft.io/t/call-for-testing-chromium-62-0-3202-62/2569/46 116 deny capability mknod, 117 ` 118 119 const browserSupportConnectedPlugAppArmorWithSandbox = ` 120 # TODO: should this be somewhere else? 121 /etc/mailcap r, 122 123 # While /usr/share/applications comes from the base runtime of the snap, it 124 # has some things that snaps actually need, so allow access to those and deny 125 # access to the others. This is duplicated from desktop for compatibility with 126 # existing snaps. 127 /usr/share/applications/ r, 128 /usr/share/applications/mimeapps.list r, 129 /usr/share/applications/xdg-open.desktop r, 130 # silence noisy denials from desktop files in core* snaps that aren't usable by 131 # snaps 132 deny /usr/share/applications/python*.desktop r, 133 deny /usr/share/applications/vim.desktop r, 134 deny /usr/share/applications/snap-handle-link.desktop r, # core16 135 136 # Chromium content api unfortunately needs these for normal operation 137 owner @{PROC}/@{pid}/fd/[0-9]* w, 138 139 # Various files in /run/udev/data needed by Chrome Settings. Leaks device 140 # information. 141 # input 142 /run/udev/data/c1:[0-9]* r, # /dev/psaux 143 /run/udev/data/c10:[0-9]* r, # /dev/adbmouse 144 /run/udev/data/c13:[0-9]* r, # /dev/input/* 145 /run/udev/data/c180:[0-9]* r, # /dev/vrbuttons 146 /run/udev/data/c4:[0-9]* r, # /dev/tty*, /dev/ttyS* 147 /run/udev/data/c5:[0-9]* r, # /dev/tty, /dev/console, etc 148 /run/udev/data/c7:[0-9]* r, # /dev/vcs* 149 /run/udev/data/+hid:* r, 150 /run/udev/data/+input:input[0-9]* r, 151 152 # screen 153 /run/udev/data/c29:[0-9]* r, # /dev/fb* 154 /run/udev/data/+backlight:* r, 155 /run/udev/data/+leds:* r, 156 157 # sound 158 /run/udev/data/c116:[0-9]* r, # alsa 159 /run/udev/data/+sound:card[0-9]* r, 160 161 # miscellaneous 162 /run/udev/data/c108:[0-9]* r, # /dev/ppp 163 /run/udev/data/c189:[0-9]* r, # USB serial converters 164 /run/udev/data/c89:[0-9]* r, # /dev/i2c-* 165 /run/udev/data/c81:[0-9]* r, # video4linux (/dev/video*, etc) 166 /run/udev/data/c202:[0-9]* r, # /dev/cpu/*/msr 167 /run/udev/data/c203:[0-9]* r, # /dev/cuse 168 /run/udev/data/+acpi:* r, 169 /run/udev/data/+hwmon:hwmon[0-9]* r, 170 /run/udev/data/+i2c:* r, 171 /sys/devices/**/bConfigurationValue r, 172 /sys/devices/**/descriptors r, 173 /sys/devices/**/manufacturer r, 174 /sys/devices/**/product r, 175 /sys/devices/**/revision r, 176 /sys/devices/**/serial r, 177 /sys/devices/**/vendor r, 178 /sys/devices/system/node/node[0-9]*/meminfo r, 179 180 # Allow getting the manufacturer and model of the 181 # computer where Chrome/chromium is currently running. 182 # This is going to be used by the upcoming Hardware Platform 183 # extension API. 184 # https://chromium.googlesource.com/chromium/src.git/+/84618eee98fdf7548905e883e63e4f693800fcfa 185 /sys/devices/virtual/dmi/id/product_name r, 186 /sys/devices/virtual/dmi/id/sys_vendor r, 187 188 # Chromium content api tries to read these. It is an information disclosure 189 # since these contain the names of snaps. Chromium operates fine without the 190 # access so just block it. 191 deny /sys/devices/virtual/block/loop[0-9]*/loop/backing_file r, 192 deny /sys/devices/virtual/block/dm-[0-9]*/dm/name r, 193 194 # networking 195 /run/udev/data/n[0-9]* r, 196 /run/udev/data/+bluetooth:hci[0-9]* r, 197 /run/udev/data/+rfkill:rfkill[0-9]* r, 198 /run/udev/data/c241:[0-9]* r, # /dev/vhost-vsock 199 200 # storage 201 /run/udev/data/b1:[0-9]* r, # /dev/ram* 202 /run/udev/data/b7:[0-9]* r, # /dev/loop* 203 /run/udev/data/b8:[0-9]* r, # /dev/sd* 204 /run/udev/data/b11:[0-9]* r, # /dev/scd* and sr* 205 /run/udev/data/b230:[0-9]* r, # /dev/zvol* 206 /run/udev/data/c21:[0-9]* r, # /dev/sg* 207 /run/udev/data/+usb:[0-9]* r, 208 209 # experimental 210 /run/udev/data/b252:[0-9]* r, 211 /run/udev/data/b253:[0-9]* r, 212 /run/udev/data/b259:[0-9]* r, 213 /run/udev/data/c24[0-9]:[0-9]* r, 214 /run/udev/data/c25[0-4]:[0-9]* r, 215 216 /sys/bus/**/devices/ r, 217 218 # Google Cloud Print 219 unix (bind) 220 type=stream 221 addr="@[0-9A-F]*._service_*", 222 223 # Policy needed only when using the chrome/chromium setuid sandbox 224 capability sys_ptrace, 225 ptrace (trace) peer=snap.@{SNAP_INSTANCE_NAME}.**, 226 unix (receive, send) peer=(label=snap.@{SNAP_INSTANCE_NAME}.**), 227 228 # If this were going to be allowed to all snaps, then for all the following 229 # rules we would want to wrap in a 'browser_sandbox' profile, but a limitation 230 # in AppArmor profile transitions prevents this. 231 # 232 # @{INSTALL_DIR}/@{SNAP_NAME}/@{SNAP_REVISION}/opt/google/chrome{,-beta,-unstable}/chrome-sandbox cx -> browser_sandbox, 233 # profile browser_sandbox { 234 # ... 235 # # This rule needs to work but generates a parser error 236 # @{INSTALL_DIR}/@{SNAP_NAME}/@{SNAP_REVISION}/opt/google/chrome/chrome px -> snap.@{SNAP_INSTANCE_NAME}.@{SNAP_APP}, 237 # @{INSTALL_DIR}/@{SNAP_INSTANCE_NAME}/@{SNAP_REVISION}/opt/google/chrome/chrome px -> snap.@{SNAP_INSTANCE_NAME}.@{SNAP_APP}, 238 # ... 239 # } 240 241 # Required for dropping into PID namespace. Keep in mind that until the 242 # process drops this capability it can escape confinement, but once it 243 # drops CAP_SYS_ADMIN we are ok. 244 capability sys_admin, 245 246 # All of these are for sanely dropping from root and chrooting 247 capability chown, 248 capability fsetid, 249 capability setgid, 250 capability setuid, 251 capability sys_chroot, 252 253 # User namespace sandbox 254 owner @{PROC}/@{pid}/setgroups rw, 255 owner @{PROC}/@{pid}/uid_map rw, 256 owner @{PROC}/@{pid}/gid_map rw, 257 258 # Webkit uses a particular SHM names # LP: 1578217 259 owner /{dev,run}/shm/WK2SharedMemory.* mrw, 260 261 # Chromium content api on (at least) later versions of Ubuntu just use this 262 owner /{dev,run}/shm/shmfd-* mrw, 263 264 # Clearing the PG_Referenced and ACCESSED/YOUNG bits provides a method to 265 # measure approximately how much memory a process is using via /proc/self/smaps 266 # (man 5 proc). This access allows the snap to clear references for pids from 267 # other snaps and the system, so it is limited to snaps that specify: 268 # allow-sandbox: true. 269 owner @{PROC}/@{pid}/clear_refs w, 270 271 # Allow setting realtime priorities. Clients require RLIMIT_RTTIME in the first 272 # place and client authorization is done via PolicyKit. Note that setrlimit() 273 # is allowed by default seccomp policy but requires 'capability sys_resource', 274 # which we deny be default. 275 # http://git.0pointer.net/rtkit.git/tree/README 276 dbus (send) 277 bus=system 278 path=/org/freedesktop/RealtimeKit1 279 interface=org.freedesktop.DBus.Properties 280 member=Get 281 peer=(name=org.freedesktop.RealtimeKit1, label=unconfined), 282 dbus (send) 283 bus=system 284 path=/org/freedesktop/RealtimeKit1 285 interface=org.freedesktop.RealtimeKit1 286 member=MakeThread{HighPriority,Realtime,RealtimeWithPID} 287 peer=(name=org.freedesktop.RealtimeKit1, label=unconfined), 288 ` 289 290 const browserSupportConnectedPlugSecComp = ` 291 # Description: Can access various APIs needed by modern browsers (eg, Google 292 # Chrome/Chromium and Mozilla) and file paths they expect. This interface is 293 # transitional and is only in place while upstream's work to change their paths 294 # and snappy is updated to properly mediate the APIs. 295 296 # for anonymous sockets 297 bind 298 listen 299 accept 300 accept4 301 302 # TODO: fine-tune when seccomp arg filtering available in stable distro 303 # releases 304 setpriority 305 306 # Since snapd still uses SECCOMP_RET_KILL, add a workaround rule to allow mknod 307 # on character devices since chromium unconditionally performs a mknod() to 308 # create the /dev/nvidiactl device, regardless of if it exists or not or if the 309 # process has CAP_MKNOD or not. Since we don't want to actually grant the 310 # ability to create character devices, we added an explicit deny AppArmor rule 311 # for this capability. When snapd uses SECCOMP_RET_ERRNO, we can remove this 312 # rule. 313 # https://forum.snapcraft.io/t/call-for-testing-chromium-62-0-3202-62/2569/46 314 mknod - |S_IFCHR - 315 mknodat - - |S_IFCHR - 316 ` 317 318 const browserSupportConnectedPlugSecCompWithSandbox = ` 319 # Policy needed only when using the chrome/chromium setuid sandbox 320 chroot 321 sched_setscheduler 322 323 # Chromium will attempt to set the affinity of it's renderer threads, primarily 324 # on android, but also on Linux where it is available. See 325 # https://github.com/chromium/chromium/blob/99314be8152e688bafbbf9a615536bdbb289ea87/content/common/android/cpu_affinity.cc#L51 326 sched_setaffinity 327 328 # TODO: fine-tune when seccomp arg filtering available in stable distro 329 # releases 330 setuid 331 setgid 332 333 # Policy needed for Mozilla userns sandbox 334 unshare 335 quotactl 336 337 # The Breakpad crash reporter uses ptrace to read register/memory state 338 # from the crashed process, but it doesn't need to modify any state; see 339 # https://bugzilla.mozilla.org/show_bug.cgi?id=1461848. 340 # 341 # These rules allow that but don't allow ptrace operations that 342 # write registers, which can be used to bypass security; see 343 # https://lkml.org/lkml/2016/5/26/354. 344 ptrace PTRACE_ATTACH 345 ptrace PTRACE_DETACH 346 ptrace PTRACE_GETREGS 347 ptrace PTRACE_GETFPREGS 348 ptrace PTRACE_GETFPXREGS 349 ptrace PTRACE_GETREGSET 350 ptrace PTRACE_PEEKDATA 351 ptrace PTRACE_PEEKUSER 352 ptrace PTRACE_CONT 353 ` 354 355 type browserSupportInterface struct{} 356 357 func (iface *browserSupportInterface) Name() string { 358 return "browser-support" 359 } 360 361 func (iface *browserSupportInterface) StaticInfo() interfaces.StaticInfo { 362 return interfaces.StaticInfo{ 363 Summary: browserSupportSummary, 364 ImplicitOnCore: true, 365 ImplicitOnClassic: true, 366 BaseDeclarationSlots: browserSupportBaseDeclarationSlots, 367 } 368 } 369 370 func (iface *browserSupportInterface) BeforePreparePlug(plug *snap.PlugInfo) error { 371 // It's fine if allow-sandbox isn't specified, but it it is, 372 // it needs to be bool 373 if v, ok := plug.Attrs["allow-sandbox"]; ok { 374 if _, ok = v.(bool); !ok { 375 return fmt.Errorf("browser-support plug requires bool with 'allow-sandbox'") 376 } 377 } 378 379 return nil 380 } 381 382 func (iface *browserSupportInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 383 var allowSandbox bool 384 _ = plug.Attr("allow-sandbox", &allowSandbox) 385 spec.AddSnippet(browserSupportConnectedPlugAppArmor) 386 if allowSandbox { 387 spec.AddSnippet(browserSupportConnectedPlugAppArmorWithSandbox) 388 } else { 389 spec.SetSuppressPtraceTrace() 390 } 391 return nil 392 } 393 394 func (iface *browserSupportInterface) SecCompConnectedPlug(spec *seccomp.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 395 var allowSandbox bool 396 _ = plug.Attr("allow-sandbox", &allowSandbox) 397 snippet := browserSupportConnectedPlugSecComp 398 if allowSandbox { 399 snippet += browserSupportConnectedPlugSecCompWithSandbox 400 } 401 spec.AddSnippet(snippet) 402 return nil 403 } 404 405 func (iface *browserSupportInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 406 return true 407 } 408 409 func init() { 410 registerIface(&browserSupportInterface{}) 411 }