github.com/rigado/snapd@v2.42.5-go-mod+incompatible/interfaces/builtin/common.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 "io/ioutil" 24 "path/filepath" 25 26 "github.com/snapcore/snapd/interfaces" 27 "github.com/snapcore/snapd/interfaces/apparmor" 28 "github.com/snapcore/snapd/interfaces/kmod" 29 "github.com/snapcore/snapd/interfaces/seccomp" 30 "github.com/snapcore/snapd/interfaces/udev" 31 "github.com/snapcore/snapd/snap" 32 ) 33 34 // evalSymlinks is either filepath.EvalSymlinks or a mocked function for 35 // applicable for testing. 36 var evalSymlinks = filepath.EvalSymlinks 37 38 // readDir is either ioutil.ReadDir or a mocked function for applicable for 39 // testing. 40 var readDir = ioutil.ReadDir 41 42 type commonInterface struct { 43 name string 44 summary string 45 docURL string 46 47 implicitOnCore bool 48 implicitOnClassic bool 49 50 baseDeclarationPlugs string 51 baseDeclarationSlots string 52 53 connectedPlugAppArmor string 54 connectedPlugSecComp string 55 connectedPlugUDev []string 56 reservedForOS bool 57 rejectAutoConnectPairs bool 58 59 connectedPlugKModModules []string 60 connectedSlotKModModules []string 61 permanentPlugKModModules []string 62 permanentSlotKModModules []string 63 64 usesPtraceTrace bool 65 suppressPtraceTrace bool 66 suppressHomeIx bool 67 controlsDeviceCgroup bool 68 } 69 70 // Name returns the interface name. 71 func (iface *commonInterface) Name() string { 72 return iface.name 73 } 74 75 // StaticInfo returns various meta-data about this interface. 76 func (iface *commonInterface) StaticInfo() interfaces.StaticInfo { 77 return interfaces.StaticInfo{ 78 Summary: iface.summary, 79 DocURL: iface.docURL, 80 ImplicitOnCore: iface.implicitOnCore, 81 ImplicitOnClassic: iface.implicitOnClassic, 82 BaseDeclarationPlugs: iface.baseDeclarationPlugs, 83 BaseDeclarationSlots: iface.baseDeclarationSlots, 84 } 85 } 86 87 func (iface *commonInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 88 if iface.usesPtraceTrace { 89 spec.SetUsesPtraceTrace() 90 } else if iface.suppressPtraceTrace { 91 spec.SetSuppressPtraceTrace() 92 } 93 if iface.suppressHomeIx { 94 spec.SetSuppressHomeIx() 95 } 96 if iface.connectedPlugAppArmor != "" { 97 spec.AddSnippet(iface.connectedPlugAppArmor) 98 } 99 return nil 100 } 101 102 // AutoConnect returns whether plug and slot should be implicitly 103 // auto-connected assuming they will be an unambiguous connection 104 // candidate and declaration-based checks allow. 105 // 106 // By default we allow what declarations allowed. 107 func (iface *commonInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 108 return !iface.rejectAutoConnectPairs 109 } 110 111 func (iface *commonInterface) KModConnectedPlug(spec *kmod.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 112 for _, m := range iface.connectedPlugKModModules { 113 if err := spec.AddModule(m); err != nil { 114 return err 115 } 116 } 117 return nil 118 } 119 120 func (iface *commonInterface) KModConnectedSlot(spec *kmod.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 121 for _, m := range iface.connectedSlotKModModules { 122 if err := spec.AddModule(m); err != nil { 123 return err 124 } 125 } 126 return nil 127 } 128 129 func (iface *commonInterface) KModPermanentPlug(spec *kmod.Specification, plug *snap.PlugInfo) error { 130 for _, m := range iface.permanentPlugKModModules { 131 if err := spec.AddModule(m); err != nil { 132 return err 133 } 134 } 135 return nil 136 } 137 138 func (iface *commonInterface) KModPermanentSlot(spec *kmod.Specification, slot *snap.SlotInfo) error { 139 for _, m := range iface.permanentSlotKModModules { 140 if err := spec.AddModule(m); err != nil { 141 return err 142 } 143 } 144 return nil 145 } 146 147 func (iface *commonInterface) SecCompConnectedPlug(spec *seccomp.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 148 if iface.connectedPlugSecComp != "" { 149 spec.AddSnippet(iface.connectedPlugSecComp) 150 } 151 return nil 152 } 153 154 func (iface *commonInterface) UDevConnectedPlug(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 155 // don't tag devices if the interface controls it's own device cgroup 156 if iface.controlsDeviceCgroup { 157 spec.SetControlsDeviceCgroup() 158 } else { 159 for _, rule := range iface.connectedPlugUDev { 160 spec.TagDevice(rule) 161 } 162 } 163 164 return nil 165 }