1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
|
// -*- Mode: Go; indent-tabs-mode: t -*-
/*
* Copyright (C) 2019 Canonical Ltd
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 3 as
* published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
package builtin
import (
"path/filepath"
"github.com/snapcore/snapd/dirs"
"github.com/snapcore/snapd/interfaces"
"github.com/snapcore/snapd/interfaces/apparmor"
"github.com/snapcore/snapd/interfaces/mount"
"github.com/snapcore/snapd/osutil"
)
const appstreamMetadataSummary = `allows access to AppStream metadata`
const appstreamMetadataBaseDeclarationSlots = `
appstream-metadata:
allow-installation:
slot-snap-type:
- core
deny-auto-connection: true
`
// Paths for upstream and collection metadata are defined in the
// AppStream specification:
// https://www.freedesktop.org/software/appstream/docs/
const appstreamMetadataConnectedPlugAppArmor = `
# Description: Allow access to AppStream metadata from the host system
# Allow access to AppStream upstream metadata files
/usr/share/metainfo/{,**} r,
/usr/share/appdata/{,**} r,
# Allow access to AppStream collection metadata
/usr/share/app-info/** r,
/var/cache/app-info/** r,
/var/lib/app-info/** r,
# Apt symlinks the DEP-11 metadata to files in /var/lib/apt/lists
/var/lib/apt/lists/*.yml.gz r,
`
var appstreamMetadataDirs = []string{
"/usr/share/metainfo",
"/usr/share/appdata",
"/usr/share/app-info",
"/var/cache/app-info",
"/var/lib/app-info",
"/var/lib/apt/lists",
}
type appstreamMetadataInterface struct {
commonInterface
}
func (iface *appstreamMetadataInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
spec.AddSnippet(appstreamMetadataConnectedPlugAppArmor)
// Generate rules to allow snap-update-ns to do its thing
emit := spec.AddUpdateNSf
for _, target := range appstreamMetadataDirs {
source := "/var/lib/snapd/hostfs" + target
emit(" # Read-only access to %s\n", target)
emit(" mount options=(bind) %s/ -> %s/,\n", source, target)
emit(" remount options=(bind, ro) %s/,\n", target)
emit(" umount %s/,\n\n", target)
// Allow constructing writable mimic to mount point We
// expect three components to already exist: /, /usr,
// and /usr/share (or equivalents under /var).
apparmor.GenWritableProfile(emit, target, 3)
}
return nil
}
func (iface *appstreamMetadataInterface) MountConnectedPlug(spec *mount.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error {
for _, dir := range appstreamMetadataDirs {
dir = filepath.Join(dirs.GlobalRootDir, dir)
if !osutil.IsDirectory(dir) {
continue
}
spec.AddMountEntry(osutil.MountEntry{
Name: "/var/lib/snapd/hostfs" + dir,
Dir: dirs.StripRootDir(dir),
Options: []string{"bind", "ro"},
})
}
return nil
}
func init() {
registerIface(&appstreamMetadataInterface{commonInterface{
name: "appstream-metadata",
summary: appstreamMetadataSummary,
implicitOnClassic: true,
baseDeclarationSlots: appstreamMetadataBaseDeclarationSlots,
}})
}
|