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

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 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  	"github.com/snapcore/snapd/interfaces"
    24  	"github.com/snapcore/snapd/interfaces/apparmor"
    25  	"github.com/snapcore/snapd/release"
    26  )
    27  
    28  const greengrassSupportSummary = `allows operating as the Greengrass service`
    29  
    30  const greengrassSupportBaseDeclarationPlugs = `
    31    greengrass-support:
    32      allow-installation: false
    33      deny-auto-connection: true
    34  `
    35  
    36  const greengrassSupportBaseDeclarationSlots = `
    37    greengrass-support:
    38      allow-installation:
    39        slot-snap-type:
    40          - core
    41      deny-auto-connection: true
    42  `
    43  
    44  const greengrassSupportConnectedPlugAppArmorCore = `
    45  # these accesses are necessary for Ubuntu Core 16, likely due to the version 
    46  # of apparmor or the kernel which doesn't resolve the upper layer of an 
    47  # overlayfs mount correctly
    48  # the accesses show up as runc trying to read from
    49  # /system-data/var/snap/greengrass/x1/ggc-writable/packages/1.7.0/var/worker/overlays/$UUID/upper/
    50  /system-data/var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/ rw,
    51  /system-data/var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/{,**} rw,
    52  `
    53  
    54  const greengrassSupportConnectedPlugAppArmor = `
    55  # Description: can manage greengrass 'things' and their sandboxes. This
    56  # policy is intentionally not restrictive and is here to help guard against
    57  # programming errors and not for security confinement. The greengrassd
    58  # daemon by design requires extensive access to the system and
    59  # cannot be effectively confined against malicious activity.
    60  
    61  # greengrassd uses 'prctl(PR_CAPBSET_DROP, ...)'
    62  capability setpcap,
    63  
    64  # Allow managing child processes (signals, OOM, ptrace, cgroups)
    65  capability kill,
    66  
    67  capability sys_resource,
    68  /sys/kernel/mm/hugepages/ r,
    69  /sys/kernel/mm/transparent_hugepage/{,**} r,
    70  owner @{PROC}/[0-9]*/oom_score_adj rw,
    71  
    72  capability sys_ptrace,
    73  ptrace (trace) peer=@{profile_name},
    74  
    75  # allow use of ggc_user and ggc_group
    76  capability chown,
    77  capability fowner,
    78  capability fsetid,
    79  capability setuid,
    80  capability setgid,
    81  
    82  # Note: when AppArmor supports fine-grained owner matching, can match on
    83  # ggc_user (LP: #1697090)
    84  @{PROC}/[0-9]*/uid_map r,
    85  @{PROC}/[0-9]*/gid_map r,
    86  @{PROC}/[0-9]*/environ r,
    87  owner @{PROC}/[0-9]*/uid_map w,
    88  owner @{PROC}/[0-9]*/gid_map w,
    89  
    90  # Allow greengrassd to read restricted non-root directories (LP: #1697090)
    91  capability dac_read_search,
    92  
    93  # overlayfs
    94  capability sys_admin,
    95  capability dac_override,  # for various overlayfs accesses
    96  
    97  # for setting up mounts
    98  @{PROC}/[0-9]*/mountinfo r,
    99  @{PROC}/filesystems r,
   100  
   101  # runc needs this
   102  @{PROC}/[0-9]*/setgroups r,
   103  
   104  # cgroup accesses
   105  # greengrassd extensively uses cgroups to confine it's containers (AKA lambdas)
   106  # and needs to read what cgroups are available; we allow reading any cgroup, 
   107  # but limit writes below
   108  # also note that currently greengrass is not implemented in such a way that it
   109  # can stack it's cgroups inside the cgroup that snapd would normally enforce
   110  # but this may change in the future
   111  # an example cgroup access looks like this:
   112  # /old_rootfs/sys/fs/cgroup/cpuset/system.slice/7d23e67f-13f5-4b7e-5a85-83f8773345a8/
   113  # the old_rootfs prefix is due to the pivot_root - the "old" rootfs is mounted
   114  # at /old_rootfs before
   115  @{PROC}/cgroups r,
   116  owner @{PROC}/[0-9]*/cgroup r,
   117  owner /old_rootfs/sys/fs/cgroup/{,**} r,
   118  owner /old_rootfs/sys/fs/cgroup/{blkio,cpuset,devices,hugetlb,memory,perf_event,pids,freezer/snap.@{SNAP_NAME}}/{,system.slice/}system.slice/ rw,
   119  owner /old_rootfs/sys/fs/cgroup/{blkio,cpuset,devices,hugetlb,memory,perf_event,pids,freezer/snap.@{SNAP_NAME}}/{,system.slice/}system.slice/[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]/{,**} rw,
   120  # separated from the above rule for clarity due to the comma in "net_cls,net_prio"
   121  owner /old_rootfs/sys/fs/cgroup/net_cls,net_prio/{,system.slice/}system.slice/ rw,
   122  owner /old_rootfs/sys/fs/cgroup/net_cls,net_prio/{,system.slice/}system.slice/[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]/{,**} rw,
   123  owner /old_rootfs/sys/fs/cgroup/cpu,cpuacct/{,system.slice/}system.slice/ rw,
   124  owner /old_rootfs/sys/fs/cgroup/cpu,cpuacct/{,system.slice/}system.slice/[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]/{,**} rw,
   125  owner /old_rootfs/sys/fs/cgroup/{devices,memory,pids,blkio,systemd}/{,system.slice/}snap.@{SNAP_NAME}.greengrass{,d.service}/system.slice/ rw,
   126  owner /old_rootfs/sys/fs/cgroup/{devices,memory,pids,blkio,systemd}/{,system.slice/}snap.@{SNAP_NAME}.greengrass{,d.service}/system.slice/[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]/{,**} rw,
   127  owner /old_rootfs/sys/fs/cgroup/cpu,cpuacct/system.slice/snap.@{SNAP_NAME}.greengrass{,d.service}/system.slice/ rw,
   128  owner /old_rootfs/sys/fs/cgroup/cpu,cpuacct/system.slice/snap.@{SNAP_NAME}.greengrass{,d.service}/system.slice/{,**} rw,
   129  # specific rule for cpuset files
   130  owner /old_rootfs/sys/fs/cgroup/cpuset/{,system.slice/}cpuset.{cpus,mems} rw,
   131  
   132  # the wrapper scripts need to use mount/umount and pivot_root from the 
   133  # core snap
   134  /bin/{,u}mount ixr,
   135  /sbin/pivot_root ixr,
   136  
   137  # allow pivot_root'ing into the rootfs prepared for the greengrass daemon
   138  # parallel-installs: SNAP_{DATA,COMMON} are remapped, need to use SNAP_NAME, for
   139  # completeness allow SNAP_INSTANCE_NAME too
   140  pivot_root
   141  	oldroot=/var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/old_rootfs/
   142  	/var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/,
   143  
   144  # miscellaneous accesses by greengrassd
   145  /sys/devices/virtual/block/loop[0-9]*/loop/autoclear r,
   146  /sys/devices/virtual/block/loop[0-9]*/loop/backing_file r,
   147  
   148  # greengrassd needs protected hardlinks, symlinks, etc to run securely, but
   149  # won't turn them on itself, hence only read access for these things -
   150  # the user is clearly informed if these are disabled and so the user can
   151  # enable these themselves rather than give the snap permission to turn these
   152  # on
   153  @{PROC}/sys/fs/protected_hardlinks r,
   154  @{PROC}/sys/fs/protected_symlinks r,
   155  @{PROC}/sys/fs/protected_fifos r,
   156  @{PROC}/sys/fs/protected_regular r,
   157  
   158  # mount tries to access this, but it doesn't really need it
   159  deny /run/mount/utab rw,
   160  
   161  # these accesses are needed in order to mount a squashfs file for the rootfs
   162  # note that these accesses allow reading other snaps and thus grants device control
   163  /dev/loop-control rw,
   164  /dev/loop[0-9]* rw,
   165  /sys/devices/virtual/block/loop[0-9]*/ r,
   166  /sys/devices/virtual/block/loop[0-9]*/** r,
   167  
   168  # mount for mounting the rootfs which is a squashfs image inside $SNAP_DATA/rootfs
   169  mount options=ro /dev/loop[0-9]* -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/,
   170  
   171  # generic mounts for allowing anything inside $SNAP_DATA to be remounted anywhere else inside $SNAP_DATA
   172  # parallel-installs: SNAP_{DATA,COMMON} are remapped, need to use SNAP_NAME, for
   173  # completeness allow SNAP_INSTANCE_NAME too
   174  mount options=(rw, bind) /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/** -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/** ,
   175  mount options=(rw, rbind) /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/** -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/** ,
   176  # also allow mounting new files anywhere underneath the rootfs of the target 
   177  # overlayfs directory, which is the rootfs of the container
   178  # this is for allowing local resource access which first makes a mount at 
   179  # the target destination and then a bind mount from the source to the destination
   180  # the source destination mount will be allowed under the above rule
   181  mount -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/**,
   182  
   183  # specific mounts for setting up the mount namespace that greengrassd runs inside
   184  mount options=(rw, bind) /proc/ -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/proc/,
   185  mount /sys -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/sys/,
   186  mount options=(rw, bind) /dev/ -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/dev/,
   187  mount options=(rw, bind) /{,var/}run/ -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/{,var/}run/,
   188  mount options=(rw, nosuid, strictatime) fstype=tmpfs tmpfs -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/dev/,
   189  # note that we don't mount a new tmpfs here so that everytime we run and setup
   190  # the mount ns for greengrassd it uses the same tmpfs which will be the tmpfs
   191  # that snapd sets up for the snap
   192  mount options=(rw, bind) /tmp/ -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/tmp/,
   193  mount options=(rw, nosuid, nodev, noexec) fstype=mqueue mqueue -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/dev/mqueue/,
   194  mount options=(rw, nosuid, noexec) fstype=devpts devpts -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/dev/pts/,
   195  mount options=(rw, nosuid, nodev, noexec) fstype=tmpfs shm -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/dev/shm/,
   196  mount fstype=proc proc -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/proc/,
   197  
   198  # mounts for setting up child container rootfs
   199  mount options=(rw, rprivate) -> /,
   200  mount options=(ro, remount, rbind) -> /,
   201  mount fstype=overlay -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/,
   202  
   203  # for jailing the process by removing the rootfs when the overlayfs is setup
   204  umount /,
   205  
   206  # mounts greengrassd performs for the containers
   207  mount fstype="tmpfs" options=(rw, nosuid, strictatime) tmpfs -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/,
   208  mount fstype="proc" proc -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/proc/,
   209  mount fstype="devpts" options=(rw, nosuid, noexec) devpts -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/pts/,
   210  mount fstype="tmpfs" options=(rw, nosuid, nodev, noexec) shm -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/shm/,
   211  mount fstype="mqueue" options=(rw, nosuid, nodev, noexec) mqueue -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/mqueue/,
   212  mount options=(ro, remount, bind) -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/lambda/,
   213  mount options=(ro, remount, bind) -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/runtime/,
   214  mount options=(rw, bind) /dev/null -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/null,
   215  mount options=(rw, bind) /dev/random -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/random,
   216  mount options=(rw, bind) /dev/full -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/full,
   217  mount options=(rw, bind) /dev/tty -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/tty,
   218  mount options=(rw, bind) /dev/zero -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/zero,
   219  mount options=(rw, bind) /dev/urandom -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/dev/urandom,
   220  
   221  # mounts for /run in the greengrassd mount namespace
   222  mount options=(rw, bind) /run/ -> /run/,
   223  
   224  # mounts for resolv.conf inside the container
   225  # we have to manually do this otherwise the go DNS resolver fails to work, because it isn't configured to 
   226  # use the system DNS server and attempts to do DNS resolution itself, manually inspecting /etc/resolv.conf
   227  mount options=(ro, bind) /run/systemd/resolve/stub-resolv.conf -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/etc/resolv.conf,
   228  mount options=(ro, bind) /run/resolvconf/resolv.conf -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/etc/resolv.conf,
   229  mount options=(ro, remount, bind) -> /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/rootfs/etc/resolv.conf,
   230  
   231  # pivot_root for the container initialization into the rootfs
   232  # note that the actual syscall is pivotroot(".",".")
   233  # so the oldroot is the same as the new root
   234  pivot_root 
   235  	oldroot=/var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/
   236  	/var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/ggc-writable/packages/*/rootfs/merged/,
   237  
   238  # mounts for /proc
   239  mount options=(ro, remount) -> /proc/{asound/,bus/,fs/,irq/,sys/,sysrq-trigger},
   240  mount options=(ro, remount, rbind) -> /proc/{asound/,bus/,fs/,irq/,sys/,sysrq-trigger},
   241  mount options=(ro, nosuid, nodev, noexec, remount, rbind) -> /proc/{asound/,bus/,fs/,irq/,sys/,sysrq-trigger},
   242  mount options=(rw, bind) /proc/asound/ -> /proc/asound/,
   243  mount options=(rw, bind) /proc/bus/ -> /proc/bus/,
   244  mount options=(rw, bind) /proc/fs/ -> /proc/fs/,
   245  mount options=(rw, bind) /proc/irq/ -> /proc/irq/,
   246  mount options=(rw, bind) /proc/sys/ -> /proc/sys/,
   247  mount options=(rw, bind) /proc/sysrq-trigger -> /proc/sysrq-trigger,
   248  
   249  # mount some devices using /dev/null
   250  mount options=(rw, bind) /dev/null -> /proc/kcore,
   251  mount options=(rw, bind) /dev/null -> /proc/sched_debug,
   252  mount options=(rw, bind) /dev/null -> /proc/timer_stats,
   253  
   254  # greengrass will also mount over /proc/latency_stats when running on
   255  # kernels configured with CONFIG_LATENCYTOP set
   256  mount options=(rw, bind) /dev/null -> /proc/latency_stats,
   257  
   258  # umounts for tearing down containers
   259  umount /var/snap/{@{SNAP_NAME},@{SNAP_INSTANCE_NAME}}/*/**,
   260  
   261  # this is for container device creation
   262  # also need mknod and mknodat in seccomp
   263  capability mknod,
   264  
   265  # for the greengrassd pid file
   266  # note we can't use layouts for this because /var/run is a symlink to /run
   267  # and /run is explicitly disallowed for use by layouts
   268  # also note that technically this access is post-pivot_root, but during the setup
   269  # for the mount ns that the snap performs (not snapd), /var/run is bind mounted
   270  # from outside the pivot_root to inside the pivot_root, so this will always 
   271  # access the same files inside or outside the pivot_root
   272  owner /{var/,}run/greengrassd.pid rw,
   273  
   274  # all of the rest of the accesses are made by child containers and as such are 
   275  # "post-pivot_root", meaning that they aren't accessing these files on the 
   276  # host root filesystem, but rather somewhere inside $SNAP_DATA/rootfs/
   277  # Note: eventually greengrass will gain the ability to specify child profiles
   278  # for it's containers and include these rules in that profile so they won't
   279  # be here, but that work isn't done yet
   280  # Additionally see LP bug #1791711 for apparmor resolving file accesses after
   281  # a pivot_root
   282  
   283  # for IPC communication via lambda helpers
   284  /[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f]-[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]/upper/{,greengrass_ipc.sock} rw,
   285  
   286  # for child container lambda certificates
   287  /certs/ r,
   288  /certs/** r,
   289  /group/ r,
   290  /group/** r,
   291  /state/ r,
   292  /state/{,**} krw,
   293  # the child containers need to use a file lock here
   294  owner /state/secretsmanager/secrets.db krw,
   295  owner /state/secretsmanager/secrets.db-journal rw,
   296  owner /state/shadow/ rw,
   297  owner /state/shadow/{,**} krw,
   298  # more specific accesses for writing
   299  owner /state/server/ rw,
   300  owner /state/server/{,**} rw,
   301  
   302  # for executing python, nodejs, java, and C (executable) lambda functions
   303  # currently the runtimes are "python2.7", "nodejs6.10", "java8" and "executable",
   304  # but those version numbers could change so we add a "*" on the end of the folders to be safe for
   305  # future potential upgrades
   306  /runtime/{python*,executable*,nodejs*,java*}/ r,
   307  /runtime/{python*,executable*,nodejs*,java*}/** r,
   308  
   309  # Ideally we would use a child profile for these but since the greengrass
   310  # sandbox is using prctl(PR_SET_NO_NEW_PRIVS, ...) we cannot since that blocks
   311  # profile transitions. With policy stacking we could use a more restrictive
   312  # child profile, but there are bugs which prevent that at this time
   313  # (LP: #1696552, LP: #1696551). As such, must simply rely on the greengrass
   314  # sandbox for now.
   315  /lambda/ r,
   316  /lambda/** ixr,
   317  
   318  # needed by cloneBinary.ensureSelfCloned()
   319  / ix,
   320  
   321  # the python runtime tries to access /etc/debian_version, presumably to identify what system it's running on
   322  # note there may be other accesses that the containers try to run...
   323  /etc/ r,
   324  /etc/debian_version r,
   325  #include <abstractions/python>
   326  # additional accesses needed for newer pythons in later bases
   327  /usr/lib{,32,64}/python3.[0-9]/**.{pyc,so}           mr,
   328  /usr/lib{,32,64}/python3.[0-9]/**.{egg,py,pth}       r,
   329  /usr/lib{,32,64}/python3.[0-9]/{site,dist}-packages/ r,
   330  /usr/lib{,32,64}/python3.[0-9]/lib-dynload/*.so      mr,
   331  /etc/python3.[0-9]/**                                r,
   332  /usr/include/python3.[0-9]*/pyconfig.h               r,
   333  
   334  # manually add java certs here
   335  # see also https://bugs.launchpad.net/apparmor/+bug/1816372
   336  /etc/ssl/certs/java/{,*} r,
   337  #include <abstractions/ssl_certs>
   338  `
   339  
   340  const greengrassSupportConnectedPlugSeccomp = `
   341  # Description: can manage greengrass 'things' and their sandboxes. This
   342  # policy is intentionally not restrictive and is here to help guard against
   343  # programming errors and not for security confinement. The greengrassd
   344  # daemon by design requires extensive access to the system and
   345  # cannot be effectively confined against malicious activity.
   346  
   347  # allow use of ggc_user and ggc_group
   348  # FIXME: seccomp arg filter by this uid/gid when supported by snap-confine
   349  lchown
   350  lchown32
   351  fchown
   352  fchown32
   353  fchownat
   354  setgroups
   355  setgroups32
   356  
   357  # for creating a new mount namespace for the containers
   358  setns - CLONE_NEWNS
   359  unshare
   360  
   361  # for overlayfs and various bind mounts
   362  mount
   363  umount2
   364  pivot_root
   365  
   366  # greengrassd calls 'sethostname("sandbox", 7)'
   367  sethostname
   368  
   369  # greengrassd sets up several session keyrings. See:
   370  # https://github.com/torvalds/linux/blob/master/Documentation/security/keys.txt
   371  # Note that the lambda functions themselves run under a seccomp sandbox setup
   372  # by greengrassd.
   373  keyctl
   374  
   375  # special character device creation is necessary for creating the overlayfs 
   376  # mounts
   377  # Unfortunately this grants device ownership to the snap.
   378  mknod - |S_IFCHR -
   379  mknodat - - |S_IFCHR -
   380  `
   381  
   382  func (iface *greengrassSupportInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
   383  	if release.OnClassic {
   384  		spec.AddSnippet(greengrassSupportConnectedPlugAppArmor)
   385  	} else {
   386  		spec.AddSnippet(greengrassSupportConnectedPlugAppArmor + greengrassSupportConnectedPlugAppArmorCore)
   387  	}
   388  	// greengrass needs to use ptrace
   389  	spec.SetUsesPtraceTrace()
   390  
   391  	return nil
   392  }
   393  
   394  type greengrassSupportInterface struct {
   395  	commonInterface
   396  }
   397  
   398  func init() {
   399  	// declare the greengrass-support interface as needing ptrace(trace)
   400  	registerIface(&greengrassSupportInterface{commonInterface{
   401  		name:                 "greengrass-support",
   402  		summary:              greengrassSupportSummary,
   403  		implicitOnCore:       true,
   404  		implicitOnClassic:    true,
   405  		baseDeclarationSlots: greengrassSupportBaseDeclarationSlots,
   406  		baseDeclarationPlugs: greengrassSupportBaseDeclarationPlugs,
   407  		connectedPlugSecComp: greengrassSupportConnectedPlugSeccomp,
   408  		controlsDeviceCgroup: true,
   409  	}})
   410  }