github.com/hugh712/snapd@v0.0.0-20200910133618-1a99902bd583/interfaces/builtin/wayland.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2017-2018 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  	"github.com/snapcore/snapd/interfaces"
    24  	"github.com/snapcore/snapd/interfaces/apparmor"
    25  	"github.com/snapcore/snapd/interfaces/seccomp"
    26  	"github.com/snapcore/snapd/interfaces/udev"
    27  	"github.com/snapcore/snapd/snap"
    28  
    29  	"strings"
    30  )
    31  
    32  const waylandSummary = `allows access to compositors supporting wayland protocol`
    33  
    34  const waylandBaseDeclarationSlots = `
    35    wayland:
    36      allow-installation:
    37        slot-snap-type:
    38          - app
    39          - core
    40      deny-connection:
    41        on-classic: false
    42      deny-auto-connection:
    43        on-classic: false
    44  `
    45  
    46  const waylandPermanentSlotAppArmor = `
    47  # Description: Allow operating as a Wayland display server. This gives privileged access
    48  # to the system.
    49  
    50  # needed since Wayland is a display server and needs to configure tty devices
    51  capability sys_tty_config,
    52  /dev/tty[0-9]* rw,
    53  
    54  # Create the Wayland socket and lock file
    55  owner /run/user/[0-9]*/wayland-[0-9]* rwk,
    56  # Allow access to common client Wayland sockets from non-snap clients
    57  /run/user/[0-9]*/{mesa,mutter,sdl,wayland-cursor,weston,xwayland}-shared-* rw,
    58  # Some Wayland based toolkits (Qt, GTK3, SDL2) and Xwayland create shm files to pass
    59  # to the server. Although they are passed by FD we still need rw access to the file.
    60  /run/user/[0-9]*/snap.*/{wayland-cursor,xwayland}-shared-* rw,
    61  
    62  # Allow reading an Xwayland Xauth file
    63  # (see https://gitlab.gnome.org/GNOME/mutter/merge_requests/626)
    64  /run/user/[0-9]*/.mutter-Xwaylandauth.* r,
    65  /run/user/[0-9]*/mutter/Xauthority r,
    66  
    67  # Allow write access to create /run/user/* to create XDG_RUNTIME_DIR (until
    68  # lp:1738197 is fixed). Note this is not needed if creating a session using
    69  # logind (as provided by the login-session-control snapd interface).
    70  /run/user/[0-9]*/ w,
    71  
    72  # Needed for mode setting via drmSetMaster() and drmDropMaster()
    73  capability sys_admin,
    74  
    75  # Weston probes this on start
    76  /sys/devices/pci**/boot_vga r,
    77  
    78  # NOTE: this allows reading and inserting all input events
    79  /dev/input/* rw,
    80  
    81  # For using udev
    82  network netlink raw,
    83  /run/udev/data/c13:[0-9]* r,
    84  /run/udev/data/+input:input[0-9]* r,
    85  /run/udev/data/+platform:* r,
    86  
    87  # MESA reads this dri config file
    88  /etc/drirc r,
    89  `
    90  
    91  const waylandPermanentSlotSecComp = `
    92  # Description: Allow operating as a Wayland server. This gives privileged access
    93  # to the system.
    94  # Needed for server launch
    95  bind
    96  listen
    97  # Needed by server upon client connect
    98  accept
    99  accept4
   100  # for udev
   101  socket AF_NETLINK - NETLINK_KOBJECT_UEVENT
   102  `
   103  
   104  const waylandConnectedSlotAppArmor = `
   105  # Allow access to common client Wayland sockets for connected snaps
   106  owner /run/user/[0-9]*/###PLUG_SECURITY_TAGS###/{mesa,mutter,sdl,wayland-cursor,weston,xwayland}-shared-* rw,
   107  `
   108  
   109  const waylandConnectedPlugAppArmor = `
   110  # Allow access to the Wayland compositor server socket
   111  owner /run/user/[0-9]*/wayland-[0-9]* rw,
   112  
   113  # Needed when using QT_QPA_PLATFORM=wayland-egl (MESA dri config)
   114  /etc/drirc r,
   115  `
   116  
   117  type waylandInterface struct{}
   118  
   119  func (iface *waylandInterface) Name() string {
   120  	return "wayland"
   121  }
   122  
   123  func (iface *waylandInterface) StaticInfo() interfaces.StaticInfo {
   124  	return interfaces.StaticInfo{
   125  		Summary:              waylandSummary,
   126  		ImplicitOnClassic:    true,
   127  		BaseDeclarationSlots: waylandBaseDeclarationSlots,
   128  	}
   129  }
   130  
   131  func (iface *waylandInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   132  	spec.AddSnippet(waylandConnectedPlugAppArmor)
   133  	return nil
   134  }
   135  
   136  func (iface *waylandInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   137  	old := "###PLUG_SECURITY_TAGS###"
   138  	new := "snap." + plug.Snap().InstanceName() // forms the snap-instance-specific subdirectory name of /run/user/*/ used for XDG_RUNTIME_DIR
   139  	snippet := strings.Replace(waylandConnectedSlotAppArmor, old, new, -1)
   140  	spec.AddSnippet(snippet)
   141  	return nil
   142  }
   143  
   144  func (iface *waylandInterface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error {
   145  	spec.AddSnippet(waylandPermanentSlotSecComp)
   146  	return nil
   147  }
   148  
   149  func (iface *waylandInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error {
   150  	spec.AddSnippet(waylandPermanentSlotAppArmor)
   151  	return nil
   152  }
   153  
   154  func (iface *waylandInterface) UDevPermanentSlot(spec *udev.Specification, slot *snap.SlotInfo) error {
   155  	spec.TriggerSubsystem("input")
   156  	spec.TagDevice(`KERNEL=="tty[0-9]*"`)
   157  	spec.TagDevice(`KERNEL=="mice"`)
   158  	spec.TagDevice(`KERNEL=="mouse[0-9]*"`)
   159  	spec.TagDevice(`KERNEL=="event[0-9]*"`)
   160  	spec.TagDevice(`KERNEL=="ts[0-9]*"`)
   161  	return nil
   162  }
   163  
   164  func (iface *waylandInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool {
   165  	// allow what declarations allowed
   166  	return true
   167  }
   168  
   169  func init() {
   170  	registerIface(&waylandInterface{})
   171  }