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