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  }