github.com/bugraaydogar/snapd@v0.0.0-20210315170335-8c70bb858939/interfaces/builtin/device_buttons.go (about) 1 // -*- Mode: Go; indent-tabs-mode: t -*- 2 3 /* 4 * Copyright (C) 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 "github.com/snapcore/snapd/interfaces" 24 "github.com/snapcore/snapd/interfaces/udev" 25 ) 26 27 const deviceButtonsSummary = `allows access to device buttons as input events` 28 29 const deviceButtonsBaseDeclarationSlots = ` 30 device-buttons: 31 allow-installation: 32 slot-snap-type: 33 - core 34 deny-auto-connection: true 35 ` 36 37 const deviceButtonsConnectedPlugAppArmor = ` 38 # Description: Allow reading and writing events to device buttons exposed as 39 # input events. 40 41 # 42 # evdev-based interface 43 # 44 45 # /dev/input/event* is unfortunately not namespaced and includes all input 46 # devices, including keyboards and mice, which allows input sniffing and 47 # injection. Until we have inode tagging of devices, we use a glob rule here 48 # and rely on udev tagging to only add evdev devices to the snap's device 49 # cgroup that are marked with ENV{ID_INPUT_KEY}=="1" and are not marked with 50 # ENV{ID_INPUT_KEYBOARD}. As such, even though AppArmor allows all evdev, 51 # the device cgroup does not. 52 /dev/input/event[0-9]* rw, 53 54 # Allow reading for supported event reports for all input devices. See 55 # https://www.kernel.org/doc/Documentation/input/event-codes.txt 56 # FIXME: this is a very minor information leak and snapd should instead query 57 # udev for the specific accesses associated with the above devices. 58 /sys/devices/**/input[0-9]*/capabilities/* r, 59 ` 60 61 // Add the device buttons realized in terms of GPIO. They come up with 62 // ENV{ID_INPUT_KEY} set to "1" value and at the same time make sure these are 63 // not a keyboard. 64 // 65 // Because of the unconditional /dev/input/event[0-9]* AppArmor rule, we need 66 // to ensure that the device cgroup is in effect even when there are no 67 // gpio keys present so that we don't give away all input to the snap. 68 var deviceButtonsConnectedPlugUDev = []string{ 69 `KERNEL=="event[0-9]*", SUBSYSTEM=="input", ENV{ID_INPUT_KEY}=="1", ENV{ID_INPUT_KEYBOARD}!="1"`, 70 `KERNEL=="full", SUBSYSTEM=="mem"`, 71 } 72 73 type deviceButtonsInterface struct { 74 commonInterface 75 } 76 77 func (iface *deviceButtonsInterface) UDevConnectedPlug(spec *udev.Specification, plug *interfaces.ConnectedPlug, slot *interfaces.ConnectedSlot) error { 78 spec.TriggerSubsystem("input/key") 79 return iface.commonInterface.UDevConnectedPlug(spec, plug, slot) 80 } 81 82 func init() { 83 registerIface(&deviceButtonsInterface{commonInterface{ 84 name: "device-buttons", 85 summary: deviceButtonsSummary, 86 implicitOnCore: true, 87 implicitOnClassic: true, 88 baseDeclarationSlots: deviceButtonsBaseDeclarationSlots, 89 connectedPlugAppArmor: deviceButtonsConnectedPlugAppArmor, 90 connectedPlugUDev: deviceButtonsConnectedPlugUDev, 91 }}) 92 }