mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
logind: add support for hidraw devices
Add support for opening /dev/hidraw devices via logind's TakeDevice(). Same semantics as our support for evdev devices, but it requires the HIDIOCREVOKE ioctl in the kernel.
This commit is contained in:
parent
16b50d4018
commit
305272ab2b
@ -12,6 +12,7 @@ ACTION=="remove", GOTO="seat_end"
|
||||
TAG=="uaccess", SUBSYSTEM!="sound", TAG+="seat"
|
||||
SUBSYSTEM=="sound", KERNEL=="card*", TAG+="seat"
|
||||
SUBSYSTEM=="input", KERNEL=="input*", TAG+="seat"
|
||||
SUBSYSTEM=="hidraw", KERNEL=="hidraw*", TAG+="seat"
|
||||
SUBSYSTEM=="graphics", KERNEL=="fb[0-9]*", TAG+="seat"
|
||||
|
||||
# Assign keyboard and LCD backlights to the seat
|
||||
|
9
src/basic/missing_hidraw.h
Normal file
9
src/basic/missing_hidraw.h
Normal file
@ -0,0 +1,9 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include <linux/hidraw.h>
|
||||
|
||||
/* b31c9d9dc343146b9f4ce67b4eee748c49296e99 (6.12) */
|
||||
#ifndef HIDIOCREVOKE
|
||||
#define HIDIOCREVOKE _IOW('H', 0x0D, int)
|
||||
#endif
|
@ -16,6 +16,7 @@
|
||||
#include "logind-session-dbus.h"
|
||||
#include "logind-session-device.h"
|
||||
#include "missing_drm.h"
|
||||
#include "missing_hidraw.h"
|
||||
#include "missing_input.h"
|
||||
#include "parse-util.h"
|
||||
|
||||
@ -105,6 +106,20 @@ static void sd_eviocrevoke(int fd) {
|
||||
}
|
||||
}
|
||||
|
||||
static void sd_hidiocrevoke(int fd) {
|
||||
static bool warned = false;
|
||||
|
||||
assert(fd >= 0);
|
||||
|
||||
if (!warned && ioctl(fd, HIDIOCREVOKE, NULL) < 0) {
|
||||
if (errno == EINVAL) {
|
||||
log_warning_errno(errno, "Kernel does not support hidraw-revocation, continuing without revoking device access: %m");
|
||||
warned = true;
|
||||
} else if (errno != ENODEV)
|
||||
log_warning_errno(errno, "Failed to revoke hidraw device, continuing without revoking device access: %m");
|
||||
}
|
||||
}
|
||||
|
||||
static int sd_drmsetmaster(int fd) {
|
||||
assert(fd >= 0);
|
||||
return RET_NERRNO(ioctl(fd, DRM_IOCTL_SET_MASTER, 0));
|
||||
@ -148,6 +163,11 @@ static int session_device_open(SessionDevice *sd, bool active) {
|
||||
sd_eviocrevoke(fd);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HIDRAW:
|
||||
if (!active)
|
||||
sd_hidiocrevoke(fd);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_UNKNOWN:
|
||||
default:
|
||||
/* fallback for devices without synchronizations */
|
||||
@ -181,12 +201,13 @@ static int session_device_start(SessionDevice *sd) {
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_EVDEV:
|
||||
/* Evdev devices are revoked while inactive. Reopen it and we are fine. */
|
||||
case DEVICE_TYPE_HIDRAW:
|
||||
/* Evdev/hidraw devices are revoked while inactive. Reopen it and we are fine. */
|
||||
r = session_device_open(sd, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
/* For evdev devices, the file descriptor might be left uninitialized. This might happen while resuming
|
||||
/* For evdev/hidraw devices, the file descriptor might be left uninitialized. This might happen while resuming
|
||||
* into a session and logind has been restarted right before. */
|
||||
close_and_replace(sd->fd, r);
|
||||
break;
|
||||
@ -230,6 +251,14 @@ static void session_device_stop(SessionDevice *sd) {
|
||||
sd_eviocrevoke(sd->fd);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_HIDRAW:
|
||||
/* Revoke access on hidraw file-descriptors during deactivation.
|
||||
* This will basically prevent any operations on the fd and
|
||||
* cannot be undone. Good side is: it needs no CAP_SYS_ADMIN
|
||||
* protection this way. */
|
||||
sd_hidiocrevoke(sd->fd);
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_UNKNOWN:
|
||||
default:
|
||||
/* fallback for devices without synchronization */
|
||||
@ -252,6 +281,9 @@ static DeviceType detect_device_type(sd_device *dev) {
|
||||
} else if (device_in_subsystem(dev, "input")) {
|
||||
if (startswith(sysname, "event"))
|
||||
return DEVICE_TYPE_EVDEV;
|
||||
} else if (device_in_subsystem(dev, "hidraw")) {
|
||||
if (startswith(sysname, "hidraw"))
|
||||
return DEVICE_TYPE_HIDRAW;
|
||||
}
|
||||
|
||||
return DEVICE_TYPE_UNKNOWN;
|
||||
@ -289,6 +321,7 @@ static int session_device_verify(SessionDevice *sd) {
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_DRM:
|
||||
case DEVICE_TYPE_HIDRAW:
|
||||
break;
|
||||
|
||||
case DEVICE_TYPE_UNKNOWN:
|
||||
|
@ -11,6 +11,7 @@ enum DeviceType {
|
||||
DEVICE_TYPE_UNKNOWN,
|
||||
DEVICE_TYPE_DRM,
|
||||
DEVICE_TYPE_EVDEV,
|
||||
DEVICE_TYPE_HIDRAW,
|
||||
};
|
||||
|
||||
struct SessionDevice {
|
||||
|
@ -27,6 +27,7 @@ CapabilityBoundingSet=CAP_SYS_ADMIN CAP_MAC_ADMIN CAP_AUDIT_CONTROL CAP_CHOWN CA
|
||||
DeviceAllow=block-* r
|
||||
DeviceAllow=char-/dev/console rw
|
||||
DeviceAllow=char-drm rw
|
||||
DeviceAllow=char-hidraw rw
|
||||
DeviceAllow=char-input rw
|
||||
DeviceAllow=char-tty rw
|
||||
DeviceAllow=char-vcs rw
|
||||
|
Loading…
Reference in New Issue
Block a user