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