gitee.com/mysnapcore/mysnapd@v0.1.0/interfaces/builtin/steam_support.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2022 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  const steamSupportSummary = `allow Steam to configure pressure-vessel containers`
    23  
    24  const steamSupportBaseDeclarationPlugs = `
    25    steam-support:
    26      allow-installation: false
    27      deny-auto-connection: true
    28  `
    29  
    30  const steamSupportBaseDeclarationSlots = `
    31    steam-support:
    32      allow-installation:
    33        slot-snap-type:
    34          - core
    35      deny-auto-connection: true
    36  `
    37  
    38  const steamSupportConnectedPlugAppArmor = `
    39  # Allow pressure-vessel to set up its Bubblewrap sandbox.
    40  /sys/kernel/ r,
    41  @{PROC}/sys/kernel/overflowuid r,
    42  @{PROC}/sys/kernel/overflowgid r,
    43  @{PROC}/sys/kernel/sched_autogroup_enabled r,
    44  @{PROC}/pressure/io r,
    45  owner @{PROC}/@{pid}/uid_map rw,
    46  owner @{PROC}/@{pid}/gid_map rw,
    47  owner @{PROC}/@{pid}/setgroups rw,
    48  owner @{PROC}/@{pid}/mounts r,
    49  owner @{PROC}/@{pid}/mountinfo r,
    50  
    51  # Create and pivot to the intermediate root
    52  mount options=(rw, rslave) -> /,
    53  mount options=(rw, silent, rslave) -> /,
    54  mount fstype=tmpfs options=(rw, nosuid, nodev) tmpfs -> /tmp/,
    55  mount options=(rw, rbind) /tmp/newroot/ -> /tmp/newroot/,
    56  pivot_root oldroot=/tmp/oldroot/ /tmp/,
    57  
    58  # Set up sandbox in /newroot
    59  mount options=(rw, rbind) /oldroot/ -> /newroot/,
    60  mount options=(rw, rbind) /oldroot/dev/ -> /newroot/dev/,
    61  mount options=(rw, rbind) /oldroot/etc/ -> /newroot/etc/,
    62  mount options=(rw, rbind) /oldroot/proc/ -> /newroot/proc/,
    63  mount options=(rw, rbind) /oldroot/sys/ -> /newroot/sys/,
    64  mount options=(rw, rbind) /oldroot/tmp/ -> /newroot/tmp/,
    65  mount options=(rw, rbind) /oldroot/var/ -> /newroot/var/,
    66  mount options=(rw, rbind) /oldroot/var/tmp/ -> /newroot/var/tmp/,
    67  mount options=(rw, rbind) /oldroot/usr/ -> /newroot/run/host/usr/,
    68  mount options=(rw, rbind) /oldroot/etc/ -> /newroot/run/host/etc/,
    69  mount options=(rw, rbind) /oldroot/usr/lib/os-release -> /newroot/run/host/os-release,
    70  
    71  # Bubblewrap performs remounts on directories it binds under /newroot
    72  # to fix up the options (since options other than MS_REC are ignored
    73  # when performing a bind mount). Ideally we could do something like:
    74  #   remount options=(bind, silent, nosuid, *) /newroot/{,**},
    75  #
    76  # But that is not supported by AppArmor. So we enumerate the possible
    77  # combinations of options Bubblewrap might use.
    78  remount options=(bind, silent, nosuid, rw) /newroot/{,**},
    79  remount options=(bind, silent, nosuid, rw, nodev) /newroot/{,**},
    80  remount options=(bind, silent, nosuid, rw, noexec) /newroot/{,**},
    81  remount options=(bind, silent, nosuid, rw, nodev, noexec) /newroot/{,**},
    82  remount options=(bind, silent, nosuid, rw, noatime) /newroot/{,**},
    83  remount options=(bind, silent, nosuid, rw, nodev, noatime) /newroot/{,**},
    84  remount options=(bind, silent, nosuid, rw, noexec, noatime) /newroot/{,**},
    85  remount options=(bind, silent, nosuid, rw, nodev, noexec, noatime) /newroot/{,**},
    86  remount options=(bind, silent, nosuid, rw, relatime) /newroot/{,**},
    87  remount options=(bind, silent, nosuid, rw, nodev, relatime) /newroot/{,**},
    88  remount options=(bind, silent, nosuid, rw, noexec, relatime) /newroot/{,**},
    89  remount options=(bind, silent, nosuid, rw, nodev, noexec, relatime) /newroot/{,**},
    90  remount options=(bind, silent, nosuid, rw, nodiratime) /newroot/{,**},
    91  remount options=(bind, silent, nosuid, rw, nodev, nodiratime) /newroot/{,**},
    92  remount options=(bind, silent, nosuid, rw, noexec, nodiratime) /newroot/{,**},
    93  remount options=(bind, silent, nosuid, rw, nodev, noexec, nodiratime) /newroot/{,**},
    94  remount options=(bind, silent, nosuid, rw, noatime, nodiratime) /newroot/{,**},
    95  remount options=(bind, silent, nosuid, rw, nodev, noatime, nodiratime) /newroot/{,**},
    96  remount options=(bind, silent, nosuid, rw, noexec, noatime, nodiratime) /newroot/{,**},
    97  remount options=(bind, silent, nosuid, rw, nodev, noexec, noatime, nodiratime) /newroot/{,**},
    98  remount options=(bind, silent, nosuid, rw, relatime, nodiratime) /newroot/{,**},
    99  remount options=(bind, silent, nosuid, rw, nodev, relatime, nodiratime) /newroot/{,**},
   100  remount options=(bind, silent, nosuid, rw, noexec, relatime, nodiratime) /newroot/{,**},
   101  remount options=(bind, silent, nosuid, rw, nodev, noexec, relatime, nodiratime) /newroot/{,**},
   102  remount options=(bind, silent, nosuid, ro) /newroot/{,**},
   103  remount options=(bind, silent, nosuid, ro, nodev) /newroot/{,**},
   104  remount options=(bind, silent, nosuid, ro, noexec) /newroot/{,**},
   105  remount options=(bind, silent, nosuid, ro, nodev, noexec) /newroot/{,**},
   106  remount options=(bind, silent, nosuid, ro, noatime) /newroot/{,**},
   107  remount options=(bind, silent, nosuid, ro, nodev, noatime) /newroot/{,**},
   108  remount options=(bind, silent, nosuid, ro, noexec, noatime) /newroot/{,**},
   109  remount options=(bind, silent, nosuid, ro, nodev, noexec, noatime) /newroot/{,**},
   110  remount options=(bind, silent, nosuid, ro, relatime) /newroot/{,**},
   111  remount options=(bind, silent, nosuid, ro, nodev, relatime) /newroot/{,**},
   112  remount options=(bind, silent, nosuid, ro, noexec, relatime) /newroot/{,**},
   113  remount options=(bind, silent, nosuid, ro, nodev, noexec, relatime) /newroot/{,**},
   114  remount options=(bind, silent, nosuid, ro, nodiratime) /newroot/{,**},
   115  remount options=(bind, silent, nosuid, ro, nodev, nodiratime) /newroot/{,**},
   116  remount options=(bind, silent, nosuid, ro, noexec, nodiratime) /newroot/{,**},
   117  remount options=(bind, silent, nosuid, ro, nodev, noexec, nodiratime) /newroot/{,**},
   118  remount options=(bind, silent, nosuid, ro, noatime, nodiratime) /newroot/{,**},
   119  remount options=(bind, silent, nosuid, ro, nodev, noatime, nodiratime) /newroot/{,**},
   120  remount options=(bind, silent, nosuid, ro, noexec, noatime, nodiratime) /newroot/{,**},
   121  remount options=(bind, silent, nosuid, ro, nodev, noexec, noatime, nodiratime) /newroot/{,**},
   122  remount options=(bind, silent, nosuid, ro, relatime, nodiratime) /newroot/{,**},
   123  remount options=(bind, silent, nosuid, ro, nodev, relatime, nodiratime) /newroot/{,**},
   124  remount options=(bind, silent, nosuid, ro, noexec, relatime, nodiratime) /newroot/{,**},
   125  remount options=(bind, silent, nosuid, ro, nodev, noexec, relatime, nodiratime) /newroot/{,**},
   126  
   127  /newroot/** rwkl,
   128  /bindfile* rw,
   129  mount options=(rw, rbind) /oldroot/opt/ -> /newroot/opt/,
   130  mount options=(rw, rbind) /oldroot/srv/ -> /newroot/srv/,
   131  mount options=(rw, rbind) /oldroot/run/udev/ -> /newroot/run/udev/,
   132  mount options=(rw, rbind) /oldroot/home/{,**} -> /newroot/home/{,**},
   133  mount options=(rw, rbind) /oldroot/snap/** -> /newroot/snap/**,
   134  mount options=(rw, rbind) /oldroot/home/**/usr/ -> /newroot/usr/,
   135  mount options=(rw, rbind) /oldroot/home/**/usr/etc/** -> /newroot/etc/**,
   136  mount options=(rw, rbind) /oldroot/home/**/usr/etc/ld.so.cache -> /newroot/run/pressure-vessel/ldso/runtime-ld.so.cache,
   137  mount options=(rw, rbind) /oldroot/home/**/usr/etc/ld.so.conf -> /newroot/run/pressure-vessel/ldso/runtime-ld.so.conf,
   138  mount options=(rw, rbind) /oldroot/mnt/{,**} -> /newroot/mnt/{,**},
   139  mount options=(rw, rbind) /oldroot/media/{,**} -> /newroot/media/{,**},
   140  mount options=(rw, rbind) /oldroot/run/media/ -> /newroot/run/media/,
   141  mount options=(rw, rbind) /oldroot/etc/nvidia/ -> /newroot/etc/nvidia/,
   142  
   143  mount options=(rw, rbind) /oldroot/etc/machine-id -> /newroot/etc/machine-id,
   144  mount options=(rw, rbind) /oldroot/etc/group -> /newroot/etc/group,
   145  mount options=(rw, rbind) /oldroot/etc/passwd -> /newroot/etc/passwd,
   146  mount options=(rw, rbind) /oldroot/etc/host.conf -> /newroot/etc/host.conf,
   147  mount options=(rw, rbind) /oldroot/etc/hosts -> /newroot/etc/hosts,
   148  mount options=(rw, rbind) /oldroot/**/*resolv.conf -> /newroot/etc/resolv.conf,
   149  mount options=(rw, rbind) /bindfile* -> /newroot/etc/timezone,
   150  
   151  mount options=(rw, rbind) /oldroot/run/systemd/journal/socket -> /newroot/run/systemd/journal/socket,
   152  mount options=(rw, rbind) /oldroot/run/systemd/journal/stdout -> /newroot/run/systemd/journal/stdout,
   153  
   154  mount options=(rw, rbind) /oldroot/usr/share/fonts/ -> /newroot/run/host/fonts/,
   155  mount options=(rw, rbind) /oldroot/usr/local/share/fonts/ -> /newroot/run/host/local-fonts/,
   156  mount options=(rw, rbind) /oldroot/{var/cache/fontconfig,usr/lib/fontconfig/cache}/ -> /newroot/run/host/fonts-cache/,
   157  mount options=(rw, rbind) /oldroot/home/**/.cache/fontconfig/ -> /newroot/run/host/user-fonts-cache/,
   158  mount options=(rw, rbind) /bindfile* -> /newroot/run/host/font-dirs.xml,
   159  
   160  mount options=(rw, rbind) /oldroot/usr/share/icons/ -> /newroot/run/host/share/icons/,
   161  mount options=(rw, rbind) /oldroot/home/**/.local/share/icons/ -> /newroot/run/host/user-share/icons/,
   162  
   163  mount options=(rw, rbind) /oldroot/run/user/[0-9]*/wayland-* -> /newroot/run/pressure-vessel/wayland-*,
   164  mount options=(rw, rbind) /oldroot/tmp/.X11-unix/X* -> /newroot/tmp/.X11-unix/X*,
   165  mount options=(rw, rbind) /bindfile* -> /newroot/run/pressure-vessel/Xauthority,
   166  
   167  mount options=(rw, rbind) /bindfile* -> /newroot/run/pressure-vessel/pulse/config,
   168  mount options=(rw, rbind) /oldroot/run/user/[0-9]*/pulse/native -> /newroot/run/pressure-vessel/pulse/native,
   169  mount options=(rw, rbind) /oldroot/dev/snd/ -> /newroot/dev/snd/,
   170  mount options=(rw, rbind) /bindfile* -> /newroot/etc/asound.conf,
   171  mount options=(rw, rbind) /oldroot/run/user/[0-9]*/bus -> /newroot/run/pressure-vessel/bus,
   172  
   173  mount options=(rw, rbind) /oldroot/run/dbus/system_bus_socket -> /newroot/run/dbus/system_bus_socket,
   174  mount options=(rw, rbind) /oldroot/run/systemd/resolve/io.systemd.Resolve -> /newroot/run/systemd/resolve/io.systemd.Resolve,
   175  mount options=(rw, rbind) /bindfile* -> /newroot/run/host/container-manager,
   176  
   177  # Allow mounting Nvidia drivers into the sandbox
   178  mount options=(rw, rbind) /oldroot/var/lib/snapd/hostfs/usr/lib/@{multiarch}/** -> /newroot/var/lib/snapd/hostfs/usr/lib/@{multiarch}/**,
   179  
   180  # Allow masking of certain directories in the sandbox
   181  mount fstype=tmpfs options=(rw, nosuid, nodev) tmpfs -> /newroot/home/*/snap/steam/common/.local/share/vulkan/implicit_layer.d/,
   182  mount fstype=tmpfs options=(rw, nosuid, nodev) tmpfs -> /newroot/run/pressure-vessel/ldso/,
   183  mount fstype=tmpfs options=(rw, nosuid, nodev) tmpfs -> /newroot/tmp/.X11-unix/,
   184  
   185  # Pivot from the intermediate root to sandbox root
   186  mount options in (rw, silent, rprivate) -> /oldroot/,
   187  umount /oldroot/,
   188  pivot_root oldroot=/newroot/ /newroot/,
   189  umount /,
   190  
   191  # Permissions needed within sandbox root
   192  deny /usr/bin/{chfn,chsh,gpasswd,mount,newgrp,passwd,su,sudo,umount} x,
   193  /usr/bin/** ixr,
   194  /usr/sbin/** ixr,
   195  /usr/lib/pressure-vessel/** ixr,
   196  /run/host/** mr,
   197  /run/pressure-vessel/** mrw,
   198  /run/host/usr/sbin/ldconfig* ixr,
   199  /run/host/usr/bin/localedef ixr,
   200  /var/cache/ldconfig/** rw,
   201  
   202  capability sys_admin,
   203  capability sys_ptrace,
   204  capability setpcap,
   205  `
   206  
   207  const steamSupportConnectedPlugSecComp = `
   208  # Description: additional permissions needed by Steam
   209  
   210  # Allow Steam to set up "pressure-vessel" containers to run games in.
   211  mount
   212  umount2
   213  pivot_root
   214  `
   215  
   216  func init() {
   217  	registerIface(&commonInterface{
   218  		name:                  "steam-support",
   219  		summary:               steamSupportSummary,
   220  		implicitOnCore:        false,
   221  		implicitOnClassic:     true,
   222  		baseDeclarationSlots:  steamSupportBaseDeclarationSlots,
   223  		baseDeclarationPlugs:  steamSupportBaseDeclarationPlugs,
   224  		connectedPlugAppArmor: steamSupportConnectedPlugAppArmor,
   225  		connectedPlugSecComp:  steamSupportConnectedPlugSecComp,
   226  	})
   227  }