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