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