github.com/kubiko/snapd@v0.0.0-20201013125620-d4f3094d9ddf/interfaces/builtin/uinput.go (about)

     1  // -*- Mode: Go; indent-tabs-mode: t -*-
     2  
     3  /*
     4   * Copyright (C) 2020 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  // https://www.kernel.org/doc/html/latest/input/uinput.html. Manually connect
    23  // because this interface allows for arbitrary input injection.
    24  const uinputSummary = `allows access to the uinput device`
    25  
    26  // While this interface grants precisely what it says it does, there is known
    27  // popular software that uses the uinput device and recommends modifying the
    28  // permissions to be 0666 (see below). Require an installation constraint to
    29  // require vetting of snap publishers in an effort to protect existing systems
    30  // with lax permissions and to protect users from arbitrary publishers who
    31  // document to both manually connect and to change the permissions on the
    32  // device.
    33  const uinputBaseDeclarationPlugs = `
    34    uinput:
    35      allow-installation: false
    36      deny-auto-connection: true
    37  `
    38  
    39  const uinputBaseDeclarationSlots = `
    40    uinput:
    41      allow-installation:
    42        slot-snap-type:
    43          - core
    44      deny-auto-connection: true
    45  `
    46  
    47  const uinputConnectedPlugAppArmor = `
    48  # Description: Allow write access to the uinput device for emulating
    49  # input devices from userspace for sending input events.
    50  
    51  /dev/uinput rw,
    52  /dev/input/uinput rw,
    53  `
    54  
    55  // The uinput device allows for injecting arbitrary input, so its default
    56  // permissions are correctly root:root 0660. Some 3rd party software (eg,
    57  // the steam controller installer) installs udev rules that change the
    58  // device to world-writable permissions (0666) as a shortcut, but this is
    59  // unsafe since it would allow any unconfined user (or any snap with this
    60  // interface connected) to inject input events into the kernel. In general
    61  // snapd should not be adjusting the permissions on the device, at least not
    62  // until snapd implements 'device access' for fine-grained control. See:
    63  // https://forum.snapcraft.io/t/multiple-users-and-groups-in-snaps/1461.
    64  var uinputConnectedPlugUDev = []string{`KERNEL=="uinput"`}
    65  
    66  type uinputInterface struct {
    67  	commonInterface
    68  }
    69  
    70  func init() {
    71  	registerIface(&uinputInterface{commonInterface{
    72  		name:                  "uinput",
    73  		summary:               uinputSummary,
    74  		implicitOnCore:        true,
    75  		implicitOnClassic:     true,
    76  		baseDeclarationPlugs:  uinputBaseDeclarationPlugs,
    77  		baseDeclarationSlots:  uinputBaseDeclarationSlots,
    78  		connectedPlugAppArmor: uinputConnectedPlugAppArmor,
    79  		connectedPlugUDev:     uinputConnectedPlugUDev,
    80  	}})
    81  }