github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/x11.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2016-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  	"strings"
    24  
    25  	"github.com/snapcore/snapd/interfaces"
    26  	"github.com/snapcore/snapd/interfaces/apparmor"
    27  	"github.com/snapcore/snapd/interfaces/seccomp"
    28  	"github.com/snapcore/snapd/interfaces/udev"
    29  	"github.com/snapcore/snapd/release"
    30  	"github.com/snapcore/snapd/snap"
    31  )
    32  
    33  const x11Summary = `allows interacting with or running as an X11 server`
    34  
    35  const x11BaseDeclarationSlots = `
    36    x11:
    37      allow-installation:
    38        slot-snap-type:
    39          - app
    40          - core
    41      deny-connection:
    42        on-classic: false
    43      deny-auto-connection:
    44        on-classic: false
    45  `
    46  
    47  const x11PermanentSlotAppArmor = `
    48  # Description: Allow operating as an X11 display server. This gives privileged access
    49  # to the system.
    50  
    51  # needed since X11 is a display server and needs to configure tty devices
    52  capability sys_tty_config,
    53  /dev/tty[0-9]* rw,
    54  
    55  # Needed for mode setting via drmSetMaster() and drmDropMaster()
    56  capability sys_admin,
    57  
    58  # NOTE: this allows reading and inserting all input events
    59  /dev/input/* rw,
    60  
    61  # For using udev
    62  network netlink raw,
    63  /run/udev/data/c13:[0-9]* r,
    64  /run/udev/data/+input:input[0-9]* r,
    65  /run/udev/data/+platform:* r,
    66  
    67  # the unix socket to use to connect to the display
    68  unix (bind, listen, accept)
    69       type=stream
    70       addr="@/tmp/.X11-unix/X[0-9]*",
    71  unix (bind, listen, accept)
    72       type=stream
    73       addr="@/tmp/.ICE-unix/[0-9]*",
    74  
    75  # On systems with Tegra drivers, X11 needs to create the socket for clients to
    76  # use.
    77  unix (bind, listen, accept)
    78       type=dgram
    79       addr="@nvidia[0-9a-f]*",
    80  
    81  # For Xorg to detect screens
    82  /sys/devices/pci**/boot_vga r,
    83  /sys/devices/pci**/resources r,
    84  `
    85  
    86  const x11PermanentSlotSecComp = `
    87  # Description: Allow operating as an X11 server. This gives privileged access
    88  # to the system.
    89  # Needed for server launch
    90  bind
    91  listen
    92  # Needed by server upon client connect
    93  accept
    94  accept4
    95  # for udev
    96  socket AF_NETLINK - NETLINK_KOBJECT_UEVENT
    97  `
    98  
    99  const x11ConnectedSlotAppArmor = `
   100  # Description: Allow clients access to the X11 server socket
   101  unix (connect, receive, send, accept)
   102      type=stream
   103      addr="@/tmp/.X11-unix/X[0-9]*"
   104      peer=(label=###PLUG_SECURITY_TAGS###),
   105  unix (connect, receive, send, accept)
   106      type=stream
   107      addr="@/tmp/.ICE-unix/[0-9]*"
   108      peer=(label=###PLUG_SECURITY_TAGS###),
   109  `
   110  
   111  const x11ConnectedPlugAppArmor = `
   112  # Description: Can access the X server. Restricted because X does not prevent
   113  # eavesdropping or apps interfering with one another.
   114  
   115  # The X abstraction doesn't check the peer label, but in this case that's
   116  # ok because x11ConnectedSlotAppArmor will limit which clients can connect
   117  # to the slot implementation.
   118  #include <abstractions/X>
   119  #include <abstractions/fonts>
   120  owner @{HOME}/.local/share/fonts/{,**} r,
   121  /var/cache/fontconfig/   r,
   122  /var/cache/fontconfig/** mr,
   123  
   124  # Allow access to the user specific copy of the xauth file specified
   125  # in the XAUTHORITY environment variable, that "snap run" creates on
   126  # startup.
   127  owner /run/user/[0-9]*/.Xauthority r,
   128  
   129  # Allow reading an Xwayland Xauth file
   130  # (see https://gitlab.gnome.org/GNOME/mutter/merge_requests/626)
   131  owner /run/user/[0-9]*/.mutter-Xwaylandauth.* r,
   132  owner /run/user/[0-9]*/mutter/Xauthority r,
   133  
   134  
   135  # Needed by QtSystems on X to detect mouse and keyboard. Note, the 'netlink
   136  # raw' rule is not finely mediated by apparmor so we mediate with seccomp arg
   137  # filtering.
   138  network netlink raw,
   139  /run/udev/data/c13:[0-9]* r,
   140  /run/udev/data/+input:* r,
   141  `
   142  
   143  const x11ConnectedPlugSecComp = `
   144  # Description: Can access the X server. Restricted because X does not prevent
   145  # eavesdropping or apps interfering with one another.
   146  
   147  # Needed by QtSystems on X to detect mouse and keyboard
   148  socket AF_NETLINK - NETLINK_KOBJECT_UEVENT
   149  bind
   150  `
   151  
   152  type x11Interface struct {
   153  	commonInterface
   154  }
   155  
   156  func (iface *x11Interface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   157  	if !release.OnClassic {
   158  		old := "###PLUG_SECURITY_TAGS###"
   159  		new := plugAppLabelExpr(plug)
   160  		snippet := strings.Replace(x11ConnectedSlotAppArmor, old, new, -1)
   161  		spec.AddSnippet(snippet)
   162  	}
   163  	return nil
   164  }
   165  
   166  func (iface *x11Interface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error {
   167  	if !release.OnClassic {
   168  		spec.AddSnippet(x11PermanentSlotSecComp)
   169  	}
   170  	return nil
   171  }
   172  
   173  func (iface *x11Interface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error {
   174  	if !release.OnClassic {
   175  		spec.AddSnippet(x11PermanentSlotAppArmor)
   176  	}
   177  	return nil
   178  }
   179  
   180  func (iface *x11Interface) UDevPermanentSlot(spec *udev.Specification, slot *snap.SlotInfo) error {
   181  	if !release.OnClassic {
   182  		spec.TriggerSubsystem("input")
   183  		spec.TagDevice(`KERNEL=="tty[0-9]*"`)
   184  		spec.TagDevice(`KERNEL=="mice"`)
   185  		spec.TagDevice(`KERNEL=="mouse[0-9]*"`)
   186  		spec.TagDevice(`KERNEL=="event[0-9]*"`)
   187  		spec.TagDevice(`KERNEL=="ts[0-9]*"`)
   188  	}
   189  	return nil
   190  }
   191  
   192  func init() {
   193  	registerIface(&x11Interface{commonInterface{
   194  		name:                  "x11",
   195  		summary:               x11Summary,
   196  		implicitOnClassic:     true,
   197  		baseDeclarationSlots:  x11BaseDeclarationSlots,
   198  		connectedPlugAppArmor: x11ConnectedPlugAppArmor,
   199  		connectedPlugSecComp:  x11ConnectedPlugSecComp,
   200  	}})
   201  }