github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/appstream_metadata.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 2019 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 "path/filepath" 24 25 "github.com/snapcore/snapd/dirs" 26 "github.com/snapcore/snapd/interfaces" 27 "github.com/snapcore/snapd/interfaces/apparmor" 28 "github.com/snapcore/snapd/interfaces/mount" 29 "github.com/snapcore/snapd/osutil" 30 ) 31 32 const appstreamMetadataSummary = `allows access to AppStream metadata` 33 34 const appstreamMetadataBaseDeclarationSlots = ` 35 appstream-metadata: 36 allow-installation: 37 slot-snap-type: 38 - core 39 deny-auto-connection: true 40 ` 41 42 // Paths for upstream and collection metadata are defined in the 43 // AppStream specification: 44 // https://www.freedesktop.org/software/appstream/docs/ 45 const appstreamMetadataConnectedPlugAppArmor = ` 46 # Description: Allow access to AppStream metadata from the host system 47 48 # Allow access to AppStream upstream metadata files 49 /usr/share/metainfo/** r, 50 /usr/share/appdata/** r, 51 52 # Allow access to AppStream collection metadata 53 /usr/share/app-info/** r, 54 /var/cache/app-info/** r, 55 /var/lib/app-info/** r, 56 57 # Apt symlinks the DEP-11 metadata to files in /var/lib/apt/lists 58 /var/lib/apt/lists/*.yml.gz r, 59 ` 60 61 var appstreamMetadataDirs = []string{ 62 "/usr/share/metainfo", 63 "/usr/share/appdata", 64 "/usr/share/app-info", 65 "/var/cache/app-info", 66 "/var/lib/app-info", 67 "/var/lib/apt/lists", 68 } 69 70 type appstreamMetadataInterface struct { 71 commonInterface 72 } 73 74 func (iface *appstreamMetadataInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 75 spec.AddSnippet(appstreamMetadataConnectedPlugAppArmor) 76 77 // Generate rules to allow snap-update-ns to do its thing 78 emit := spec.EmitUpdateNSFunc() 79 for _, target := range appstreamMetadataDirs { 80 source := "/var/lib/snapd/hostfs" + target 81 emit(" # Read-only access to %s\n", target) 82 emit(" mount options=(bind) %s/ -> %s/,\n", source, target) 83 emit(" remount options=(bind, ro) %s/,\n", target) 84 emit(" umount %s/,\n\n", target) 85 // Allow constructing writable mimic to mount point We 86 // expect three components to already exist: /, /usr, 87 // and /usr/share (or equivalents under /var). 88 apparmor.GenWritableProfile(emit, target, 3) 89 } 90 return nil 91 } 92 93 func (iface *appstreamMetadataInterface) MountConnectedPlug(spec *mount.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 94 for _, dir := range appstreamMetadataDirs { 95 dir = filepath.Join(dirs.GlobalRootDir, dir) 96 if !osutil.IsDirectory(dir) { 97 continue 98 } 99 spec.AddMountEntry(osutil.MountEntry{ 100 Name: "/var/lib/snapd/hostfs" + dir, 101 Dir: dirs.StripRootDir(dir), 102 Options: []string{"bind", "ro"}, 103 }) 104 } 105 106 return nil 107 } 108 109 func init() { 110 registerIface(&appstreamMetadataInterface{commonInterface{ 111 name: "appstream-metadata", 112 summary: appstreamMetadataSummary, 113 implicitOnClassic: true, 114 reservedForOS: true, 115 baseDeclarationSlots: appstreamMetadataBaseDeclarationSlots, 116 }}) 117 }