github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/home.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2016-2018 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 "fmt" 24 "github.com/snapcore/snapd/interfaces" 25 "github.com/snapcore/snapd/interfaces/apparmor" 26 "github.com/snapcore/snapd/snap" 27 ) 28 29 const homeSummary = `allows access to non-hidden files in the home directory` 30 31 const homeBaseDeclarationSlots = ` 32 home: 33 allow-installation: 34 slot-snap-type: 35 - core 36 deny-connection: 37 plug-attributes: 38 read: all 39 deny-auto-connection: 40 - 41 on-classic: false 42 - 43 plug-attributes: 44 read: all 45 ` 46 47 const homeConnectedPlugAppArmor = ` 48 # Description: Can access non-hidden files in user's $HOME. This is restricted 49 # because it gives file access to all of the user's $HOME. 50 51 # Note, @{HOME} is the user's $HOME, not the snap's $HOME 52 53 # Allow read access to toplevel $HOME for the user 54 owner @{HOME}/ r, 55 56 # Allow read/write access to all files in @{HOME}, except snap application 57 # data in @{HOME}/snap and toplevel hidden directories in @{HOME}. 58 owner @{HOME}/[^s.]** rwkl###HOME_IX###, 59 owner @{HOME}/s[^n]** rwkl###HOME_IX###, 60 owner @{HOME}/sn[^a]** rwkl###HOME_IX###, 61 owner @{HOME}/sna[^p]** rwkl###HOME_IX###, 62 owner @{HOME}/snap[^/]** rwkl###HOME_IX###, 63 64 # Allow creating a few files not caught above 65 owner @{HOME}/{s,sn,sna}{,/} rwkl###HOME_IX###, 66 67 # Allow access to @{HOME}/snap/ to allow directory traversals from 68 # @{HOME}/snap/@{SNAP_INSTANCE_NAME} through @{HOME}/snap to @{HOME}. 69 # While this leaks snap names, it fixes usability issues for snaps 70 # that require this transitional interface. 71 owner @{HOME}/snap/ r, 72 73 # Allow access to gvfs mounts for files owned by the user (including hidden 74 # files; only allow writes to files, not the mount point). 75 owner /run/user/[0-9]*/gvfs/{,**} r, 76 owner /run/user/[0-9]*/gvfs/*/** w, 77 78 # Disallow writes to the well-known directory included in 79 # the user's PATH on several distributions 80 audit deny @{HOME}/bin/{,**} wl, 81 ` 82 83 const homeConnectedPlugAppArmorWithAllRead = ` 84 # Allow non-owner read to non-hidden and non-snap files and directories 85 capability dac_read_search, 86 @{HOME}/ r, 87 @{HOME}/[^s.]** r, 88 @{HOME}/s[^n]** r, 89 @{HOME}/sn[^a]** r, 90 @{HOME}/sna[^p]** r, 91 @{HOME}/snap[^/]** r, 92 @{HOME}/{s,sn,sna}{,/} r, 93 ` 94 95 type homeInterface struct { 96 commonInterface 97 } 98 99 func (iface *homeInterface) BeforePreparePlug(plug *snap.PlugInfo) error { 100 // It's fine if 'read' isn't specified, but if it is, it needs to be 101 // 'all' 102 if r, ok := plug.Attrs["read"]; ok && r != "all" { 103 return fmt.Errorf(`home plug requires "read" be 'all'`) 104 } 105 106 return nil 107 } 108 109 func (iface *homeInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 110 var read string 111 _ = plug.Attr("read", &read) 112 // 'owner' is the standard policy 113 spec.AddSnippet(homeConnectedPlugAppArmor) 114 115 // 'all' grants standard policy plus read access to home without owner 116 // match 117 if read == "all" { 118 spec.AddSnippet(homeConnectedPlugAppArmorWithAllRead) 119 } 120 return nil 121 } 122 123 func init() { 124 registerIface(&homeInterface{commonInterface{ 125 name: "home", 126 summary: homeSummary, 127 implicitOnCore: true, 128 implicitOnClassic: true, 129 baseDeclarationSlots: homeBaseDeclarationSlots, 130 reservedForOS: true, 131 }}) 132 }