github.com/freetocompute/snapd@v0.0.0-20210618182524-2fb355d72fd9/cmd/snap-update-ns/system.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 main 21 22 import ( 23 "fmt" 24 25 "github.com/snapcore/snapd/dirs" 26 "github.com/snapcore/snapd/snap" 27 ) 28 29 // SystemProfileUpdateContext contains information about update to system-wide mount namespace. 30 type SystemProfileUpdateContext struct { 31 CommonProfileUpdateContext 32 } 33 34 // NewSystemProfileUpdateContext returns encapsulated information for performing a per-user mount namespace update. 35 func NewSystemProfileUpdateContext(instanceName string, fromSnapConfine bool) *SystemProfileUpdateContext { 36 return &SystemProfileUpdateContext{CommonProfileUpdateContext: CommonProfileUpdateContext{ 37 instanceName: instanceName, 38 fromSnapConfine: fromSnapConfine, 39 currentProfilePath: currentSystemProfilePath(instanceName), 40 desiredProfilePath: desiredSystemProfilePath(instanceName), 41 }} 42 } 43 44 // Assumptions returns information about file system mutability rules. 45 // 46 // System mount profiles can write to /tmp (this is required for constructing 47 // writable mimics) to /var/snap (where $SNAP_DATA is for services), /snap/$SNAP_NAME, 48 // and, in case of instances, /snap/$SNAP_INSTANCE_NAME. 49 func (upCtx *SystemProfileUpdateContext) Assumptions() *Assumptions { 50 // Allow creating directories related to this snap name. 51 // 52 // Note that we allow /var/snap instead of /var/snap/$SNAP_NAME because 53 // content interface connections can readily create missing mount points on 54 // both sides of the interface connection. 55 // 56 // We scope /snap/$SNAP_NAME because only one side of the connection can be 57 // created, as snaps are read-only, the mimic construction will kick-in and 58 // create the missing directory but this directory is only visible from the 59 // snap that we are operating on (either plug or slot side, the point is, 60 // the mount point is not universally visible). 61 // 62 // /snap/$SNAP_NAME needs to be there as the code that creates such mount 63 // points must traverse writable host filesystem that contains /snap/*/ and 64 // normally such access is off-limits. This approach allows /snap/foo 65 // without allowing /snap/bin, for example. 66 // 67 // /snap/$SNAP_INSTANCE_NAME and /snap/$SNAP_NAME are added to allow 68 // remapping for parallel installs only when the snap has an instance key 69 as := &Assumptions{} 70 instanceName := upCtx.InstanceName() 71 as.AddUnrestrictedPaths("/tmp", "/var/snap", "/snap/"+instanceName) 72 if snapName := snap.InstanceSnap(instanceName); snapName != instanceName { 73 as.AddUnrestrictedPaths("/snap/" + snapName) 74 } 75 // Allow snap-update-ns to write to host's /tmp directory. This is 76 // specifically here to allow two snaps to share X11 sockets that are placed 77 // in the /tmp/.X11-unix/ directory in the private /tmp directories provided 78 // by snap-confine. The X11 interface cannot offer a precise permission for 79 // the slot-side snap, as there is no mechanism to convey this information. 80 // As such, provide write access to all of /tmp. 81 as.AddUnrestrictedPaths("/var/lib/snapd/hostfs/tmp") 82 as.AddModeHint("/var/lib/snapd/hostfs/tmp/snap.*", 0700) 83 as.AddModeHint("/var/lib/snapd/hostfs/tmp/snap.*/tmp", 1777) 84 // This is to ensure that unprivileged users can create the socket. This 85 // permission only matters if the plug-side app constructs its mount 86 // namespace before the slot-side app is launched. 87 as.AddModeHint("/var/lib/snapd/hostfs/tmp/snap.*/tmp/.X11-unix", 1777) 88 return as 89 } 90 91 // desiredSystemProfilePath returns the path of the fstab-like file with the desired, system-wide mount profile for a snap. 92 func desiredSystemProfilePath(snapName string) string { 93 return fmt.Sprintf("%s/snap.%s.fstab", dirs.SnapMountPolicyDir, snapName) 94 } 95 96 // currentSystemProfilePath returns the path of the fstab-like file with the applied, system-wide mount profile for a snap. 97 func currentSystemProfilePath(snapName string) string { 98 return fmt.Sprintf("%s/snap.%s.fstab", dirs.SnapRunNsDir, snapName) 99 }