aboutsummaryrefslogtreecommitdiff
path: root/SOURCES/0001-add-revoke_all-ioctl-to-release-event-and-joy-nodes-.patch
diff options
context:
space:
mode:
Diffstat (limited to 'SOURCES/0001-add-revoke_all-ioctl-to-release-event-and-joy-nodes-.patch')
-rw-r--r--SOURCES/0001-add-revoke_all-ioctl-to-release-event-and-joy-nodes-.patch208
1 files changed, 208 insertions, 0 deletions
diff --git a/SOURCES/0001-add-revoke_all-ioctl-to-release-event-and-joy-nodes-.patch b/SOURCES/0001-add-revoke_all-ioctl-to-release-event-and-joy-nodes-.patch
new file mode 100644
index 0000000..71d9c59
--- /dev/null
+++ b/SOURCES/0001-add-revoke_all-ioctl-to-release-event-and-joy-nodes-.patch
@@ -0,0 +1,208 @@
+From e24eba6f9ffd2338028116ddc1e14ba5b68b997a Mon Sep 17 00:00:00 2001
+From: antheas <antheas@users.noreply.github.com>
+Date: Wed, 17 Jul 2024 17:14:06 +0300
+Subject: [PATCH] add revoke_all ioctl to release event and joy nodes after
+ hiding
+
+---
+ drivers/input/evdev.c | 24 ++++++++++++++++
+ drivers/input/joydev.c | 54 ++++++++++++++++++++++++++++++-----
+ include/uapi/linux/input.h | 1 +
+ include/uapi/linux/joystick.h | 4 +++
+ 4 files changed, 76 insertions(+), 7 deletions(-)
+
+diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c
+index 51e0c4954600..87226069d076 100644
+--- a/drivers/input/evdev.c
++++ b/drivers/input/evdev.c
+@@ -951,6 +951,21 @@ static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,
+ return 0;
+ }
+
++static int evdev_revoke_all(struct evdev *evdev, struct file *file)
++{
++ struct evdev_client *client;
++ input_flush_device(&evdev->handle, file);
++
++ spin_lock(&evdev->client_lock);
++ list_for_each_entry(client, &evdev->client_list, node) {
++ client->revoked = true;
++ evdev_ungrab(evdev, client);
++ wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR);
++ }
++ spin_unlock(&evdev->client_lock);
++ return 0;
++}
++
+ /* must be called with evdev-mutex held */
+ static int evdev_set_mask(struct evdev_client *client,
+ unsigned int type,
+@@ -1094,6 +1109,15 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd,
+ return -EINVAL;
+ else
+ return evdev_revoke(evdev, client, file);
++
++ case EVIOCREVOKEALL:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (p)
++ return -EINVAL;
++ else
++ return evdev_revoke_all(evdev, file);
+
+ case EVIOCGMASK: {
+ void __user *codes_ptr;
+diff --git a/drivers/input/joydev.c b/drivers/input/joydev.c
+index 5824bca02e5a..3bdf3a1971f7 100644
+--- a/drivers/input/joydev.c
++++ b/drivers/input/joydev.c
+@@ -63,8 +63,29 @@ struct joydev_client {
+ struct fasync_struct *fasync;
+ struct joydev *joydev;
+ struct list_head node;
++ bool revoked;
+ };
+
++static int joydev_revoke(struct joydev *joydev, struct joydev_client *client)
++{
++ client->revoked = true;
++ wake_up_interruptible(&joydev->wait);
++ return 0;
++}
++
++static int joydev_revoke_all(struct joydev *joydev)
++{
++ struct joydev_client *client;
++
++ spin_lock(&joydev->client_lock);
++ list_for_each_entry(client, &joydev->client_list, node) {
++ client->revoked = true;
++ }
++ spin_unlock(&joydev->client_lock);
++ wake_up_interruptible(&joydev->wait);
++ return 0;
++}
++
+ static int joydev_correct(int value, struct js_corr *corr)
+ {
+ switch (corr->type) {
+@@ -89,6 +110,9 @@ static void joydev_pass_event(struct joydev_client *client,
+ struct js_event *event)
+ {
+ struct joydev *joydev = client->joydev;
++
++ if (client->revoked)
++ return;
+
+ /*
+ * IRQs already disabled, just acquire the lock
+@@ -345,6 +369,9 @@ static ssize_t joydev_0x_read(struct joydev_client *client,
+ struct JS_DATA_TYPE data;
+ int i;
+
++ if (client->revoked)
++ return -ENODEV;
++
+ spin_lock_irq(&input->event_lock);
+
+ /*
+@@ -402,7 +429,7 @@ static ssize_t joydev_read(struct file *file, char __user *buf,
+ return -EAGAIN;
+
+ retval = wait_event_interruptible(joydev->wait,
+- !joydev->exist || joydev_data_pending(client));
++ !joydev->exist || client->revoked || joydev_data_pending(client));
+ if (retval)
+ return retval;
+
+@@ -438,7 +465,7 @@ static __poll_t joydev_poll(struct file *file, poll_table *wait)
+
+ poll_wait(file, &joydev->wait, wait);
+ return (joydev_data_pending(client) ? (EPOLLIN | EPOLLRDNORM) : 0) |
+- (joydev->exist ? 0 : (EPOLLHUP | EPOLLERR));
++ (joydev->exist && !client->revoked ? 0 : (EPOLLHUP | EPOLLERR));
+ }
+
+ static int joydev_handle_JSIOCSAXMAP(struct joydev *joydev,
+@@ -506,9 +533,8 @@ static int joydev_handle_JSIOCSBTNMAP(struct joydev *joydev,
+ return retval;
+ }
+
+-
+-static int joydev_ioctl_common(struct joydev *joydev,
+- unsigned int cmd, void __user *argp)
++static int joydev_ioctl_common(struct joydev *joydev, struct joydev_client *client,
++ unsigned int cmd, void __user *argp)
+ {
+ struct input_dev *dev = joydev->handle.dev;
+ size_t len;
+@@ -556,6 +582,20 @@ static int joydev_ioctl_common(struct joydev *joydev,
+ return copy_to_user(argp, joydev->corr,
+ sizeof(joydev->corr[0]) * joydev->nabs) ? -EFAULT : 0;
+
++ case JSIOCREVOKE:
++ if (argp)
++ return -EINVAL;
++ else
++ return joydev_revoke(joydev, client);
++
++ case JSIOCREVOKEALL:
++ if (!capable(CAP_SYS_ADMIN))
++ return -EACCES;
++
++ if (argp)
++ return -EINVAL;
++ else
++ return joydev_revoke_all(joydev);
+ }
+
+ /*
+@@ -649,7 +689,7 @@ static long joydev_compat_ioctl(struct file *file,
+ break;
+
+ default:
+- retval = joydev_ioctl_common(joydev, cmd, argp);
++ retval = joydev_ioctl_common(joydev, client, cmd, argp);
+ break;
+ }
+
+@@ -699,7 +739,7 @@ static long joydev_ioctl(struct file *file,
+ break;
+
+ default:
+- retval = joydev_ioctl_common(joydev, cmd, argp);
++ retval = joydev_ioctl_common(joydev, client, cmd, argp);
+ break;
+ }
+ out:
+diff --git a/include/uapi/linux/input.h b/include/uapi/linux/input.h
+index 2557eb7b0561..38bfac937add 100644
+--- a/include/uapi/linux/input.h
++++ b/include/uapi/linux/input.h
+@@ -185,6 +185,7 @@ struct input_mask {
+
+ #define EVIOCGRAB _IOW('E', 0x90, int) /* Grab/Release device */
+ #define EVIOCREVOKE _IOW('E', 0x91, int) /* Revoke device access */
++#define EVIOCREVOKEALL _IOW('E', 0x94, int) /* Revoke device access from all clients. Requires CAP_SYS_ADMIN. */
+
+ /**
+ * EVIOCGMASK - Retrieve current event mask
+diff --git a/include/uapi/linux/joystick.h b/include/uapi/linux/joystick.h
+index 192bf2cf182d..543b004802f3 100644
+--- a/include/uapi/linux/joystick.h
++++ b/include/uapi/linux/joystick.h
+@@ -66,6 +66,10 @@ struct js_event {
+ #define JSIOCSBTNMAP _IOW('j', 0x33, __u16[KEY_MAX - BTN_MISC + 1]) /* set button mapping */
+ #define JSIOCGBTNMAP _IOR('j', 0x34, __u16[KEY_MAX - BTN_MISC + 1]) /* get button mapping */
+
++#define JSIOCREVOKE _IOW('j', 0x91, int) /* Revoke device access */
++#define JSIOCREVOKEALL _IOW('j', 0x94, int) /* Revoke device access from all clients. Requires CAP_SYS_ADMIN. */
++
++
+ /*
+ * Types and constants for get/set correction
+ */
+--
+2.45.2
+