github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/interfaces/builtin/mir.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 dtails. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program. 17 * 18 */ 19 20 package builtin 21 22 import ( 23 "strings" 24 25 "github.com/snapcore/snapd/interfaces" 26 "github.com/snapcore/snapd/interfaces/apparmor" 27 "github.com/snapcore/snapd/interfaces/seccomp" 28 "github.com/snapcore/snapd/interfaces/udev" 29 "github.com/snapcore/snapd/snap" 30 ) 31 32 const mirSummary = `allows operating as the Mir server` 33 34 const mirBaseDeclarationSlots = ` 35 mir: 36 allow-installation: 37 slot-snap-type: 38 - app 39 deny-connection: true 40 ` 41 42 const mirPermanentSlotAppArmor = ` 43 # Description: Allow operating as the Mir server. This gives privileged access 44 # to the system. 45 46 # needed since Mir is the display server, to configure tty devices 47 capability sys_tty_config, 48 /dev/tty[0-9]* rw, 49 50 # mir uses open("/dev/shm", O_TMPFILE...) which shows up in AppArmor 51 # as /dev/shm/#NUMBER. This is then fed to mmap with MAP_SHARED 52 # for communication with the client (note that the file doesn't actually 53 # exist and isn't accessible by other processes). Also see: 54 # https://www.kernel.org/doc/gorman/html/understand/understand015.html 55 /{dev,run}/shm/\#[0-9]* mrw, 56 57 /run/mir_socket rw, 58 /run/user/[0-9]*/mir_socket rw, 59 60 # Needed for mode setting via drmSetMaster() and drmDropMaster() 61 capability sys_admin, 62 63 # NOTE: this allows reading and inserting all input events 64 /dev/input/* rw, 65 66 # For using udev 67 network netlink raw, 68 /run/udev/data/c13:[0-9]* r, 69 /run/udev/data/+input:input[0-9]* r, 70 /run/udev/data/+platform:* r, 71 ` 72 73 const mirPermanentSlotSecComp = ` 74 # Description: Allow operating as the mir server. This gives privileged access 75 # to the system. 76 # Needed for server launch 77 bind 78 listen 79 # Needed by server upon client connect 80 accept 81 accept4 82 shmctl 83 # for udev 84 socket AF_NETLINK - NETLINK_KOBJECT_UEVENT 85 ` 86 87 const mirConnectedSlotAppArmor = ` 88 # Description: Permit clients to use Mir 89 unix (receive, send) type=seqpacket addr=none peer=(label=###PLUG_SECURITY_TAGS###), 90 ` 91 92 const mirConnectedPlugAppArmor = ` 93 # Description: Permit clients to use Mir 94 unix (receive, send) type=seqpacket addr=none peer=(label=###SLOT_SECURITY_TAGS###), 95 /run/mir_socket rw, 96 /run/user/[0-9]*/mir_socket rw, 97 98 # Mir uses /dev/shm for sharing memory with clients 99 /{dev,run}/shm/\#[0-9]* mrw, 100 ` 101 102 type mirInterface struct{} 103 104 func (iface *mirInterface) Name() string { 105 return "mir" 106 } 107 108 func (iface *mirInterface) StaticInfo() interfaces.StaticInfo { 109 return interfaces.StaticInfo{ 110 Summary: mirSummary, 111 BaseDeclarationSlots: mirBaseDeclarationSlots, 112 } 113 } 114 115 func (iface *mirInterface) AppArmorConnectedPlug(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 116 old := "###SLOT_SECURITY_TAGS###" 117 new := slotAppLabelExpr(slot) 118 snippet := strings.Replace(mirConnectedPlugAppArmor, old, new, -1) 119 spec.AddSnippet(snippet) 120 return nil 121 } 122 123 func (iface *mirInterface) AppArmorConnectedSlot(spec *apparmor.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 124 old := "###PLUG_SECURITY_TAGS###" 125 new := plugAppLabelExpr(plug) 126 snippet := strings.Replace(mirConnectedSlotAppArmor, old, new, -1) 127 spec.AddSnippet(snippet) 128 return nil 129 } 130 131 func (iface *mirInterface) AppArmorPermanentSlot(spec *apparmor.Specification, slot *snap.SlotInfo) error { 132 spec.AddSnippet(mirPermanentSlotAppArmor) 133 return nil 134 } 135 136 func (iface *mirInterface) SecCompPermanentSlot(spec *seccomp.Specification, slot *snap.SlotInfo) error { 137 spec.AddSnippet(mirPermanentSlotSecComp) 138 return nil 139 } 140 141 func (iface *mirInterface) UDevPermanentSlot(spec *udev.Specification, slot *snap.SlotInfo) error { 142 spec.TriggerSubsystem("input") 143 spec.TagDevice(`KERNEL=="tty[0-9]*"`) 144 spec.TagDevice(`KERNEL=="mice"`) 145 spec.TagDevice(`KERNEL=="mouse[0-9]*"`) 146 spec.TagDevice(`KERNEL=="event[0-9]*"`) 147 spec.TagDevice(`KERNEL=="ts[0-9]*"`) 148 return nil 149 } 150 151 func (iface *mirInterface) AutoConnect(*snap.PlugInfo, *snap.SlotInfo) bool { 152 return true 153 } 154 155 func init() { 156 registerIface(&mirInterface{}) 157 }