134 lines
3.9 KiB
Diff
134 lines
3.9 KiB
Diff
|
---
|
||
|
drivers/input/misc/uinput.c | 48 +++++++++++++++++++++++++------------
|
||
|
include/uapi/linux/uinput.h | 5 ++++
|
||
|
2 files changed, 38 insertions(+), 15 deletions(-)
|
||
|
|
||
|
|
||
|
diff --git a/drivers/input/misc/uinput.c b/drivers/input/misc/uinput.c
|
||
|
index 84051f20b18a..2c3180370a02 100644
|
||
|
--- a/drivers/input/misc/uinput.c
|
||
|
+++ b/drivers/input/misc/uinput.c
|
||
|
@@ -20,6 +20,7 @@
|
||
|
*/
|
||
|
#include <uapi/linux/uinput.h>
|
||
|
#include <linux/poll.h>
|
||
|
+#include <linux/printk.h>
|
||
|
#include <linux/sched.h>
|
||
|
#include <linux/slab.h>
|
||
|
#include <linux/module.h>
|
||
|
@@ -280,7 +281,7 @@ static int uinput_dev_flush(struct input_dev *dev, struct file *file)
|
||
|
|
||
|
static void uinput_destroy_device(struct uinput_device *udev)
|
||
|
{
|
||
|
- const char *name, *phys;
|
||
|
+ const char *name, *phys, *uniq;
|
||
|
struct input_dev *dev = udev->dev;
|
||
|
enum uinput_state old_state = udev->state;
|
||
|
|
||
|
@@ -289,6 +290,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
|
||
|
if (dev) {
|
||
|
name = dev->name;
|
||
|
phys = dev->phys;
|
||
|
+ uniq = dev->uniq;
|
||
|
if (old_state == UIST_CREATED) {
|
||
|
uinput_flush_requests(udev);
|
||
|
input_unregister_device(dev);
|
||
|
@@ -297,6 +299,7 @@ static void uinput_destroy_device(struct uinput_device *udev)
|
||
|
}
|
||
|
kfree(name);
|
||
|
kfree(phys);
|
||
|
+ kfree(uniq);
|
||
|
udev->dev = NULL;
|
||
|
}
|
||
|
}
|
||
|
@@ -831,6 +834,24 @@ static int uinput_str_to_user(void __user *dest, const char *str,
|
||
|
return ret ? -EFAULT : len;
|
||
|
}
|
||
|
|
||
|
+static int uinput_get_user_str(struct uinput_device *udev, const char **kptr,
|
||
|
+ const char *uptr, unsigned int size)
|
||
|
+{
|
||
|
+ char *tmp;
|
||
|
+
|
||
|
+ if (udev->state == UIST_CREATED)
|
||
|
+ return -EINVAL;
|
||
|
+
|
||
|
+ tmp = strndup_user(uptr, size);
|
||
|
+ if (IS_ERR(tmp))
|
||
|
+ return PTR_ERR(tmp);
|
||
|
+
|
||
|
+ kfree(*kptr);
|
||
|
+ *kptr = tmp;
|
||
|
+
|
||
|
+ return 0;
|
||
|
+}
|
||
|
+
|
||
|
static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
|
||
|
unsigned long arg, void __user *p)
|
||
|
{
|
||
|
@@ -839,7 +860,6 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
|
||
|
struct uinput_ff_upload ff_up;
|
||
|
struct uinput_ff_erase ff_erase;
|
||
|
struct uinput_request *req;
|
||
|
- char *phys;
|
||
|
const char *name;
|
||
|
unsigned int size;
|
||
|
|
||
|
@@ -916,19 +936,8 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
|
||
|
goto out;
|
||
|
|
||
|
case UI_SET_PHYS:
|
||
|
- if (udev->state == UIST_CREATED) {
|
||
|
- retval = -EINVAL;
|
||
|
- goto out;
|
||
|
- }
|
||
|
-
|
||
|
- phys = strndup_user(p, 1024);
|
||
|
- if (IS_ERR(phys)) {
|
||
|
- retval = PTR_ERR(phys);
|
||
|
- goto out;
|
||
|
- }
|
||
|
-
|
||
|
- kfree(udev->dev->phys);
|
||
|
- udev->dev->phys = phys;
|
||
|
+ pr_warn_once("uinput: UI_SET_PHYS is deprecated. Use UI_SET_PHYS_STR");
|
||
|
+ retval = uinput_get_user_str(udev, &udev->dev->phys, p, 1024);
|
||
|
goto out;
|
||
|
|
||
|
case UI_BEGIN_FF_UPLOAD:
|
||
|
@@ -1023,6 +1032,15 @@ static long uinput_ioctl_handler(struct file *file, unsigned int cmd,
|
||
|
case UI_ABS_SETUP & ~IOCSIZE_MASK:
|
||
|
retval = uinput_abs_setup(udev, p, size);
|
||
|
goto out;
|
||
|
+
|
||
|
+ case UI_SET_PHYS_STR(0):
|
||
|
+ retval = uinput_get_user_str(udev, &udev->dev->phys, p, size);
|
||
|
+ goto out;
|
||
|
+
|
||
|
+ case UI_SET_UNIQ_STR(0):
|
||
|
+ retval = uinput_get_user_str(udev, &udev->dev->uniq, p, size);
|
||
|
+ goto out;
|
||
|
+
|
||
|
}
|
||
|
|
||
|
retval = -EINVAL;
|
||
|
diff --git a/include/uapi/linux/uinput.h b/include/uapi/linux/uinput.h
|
||
|
index c9e677e3af1d..84d4fa142830 100644
|
||
|
--- a/include/uapi/linux/uinput.h
|
||
|
+++ b/include/uapi/linux/uinput.h
|
||
|
@@ -142,9 +142,14 @@ struct uinput_abs_setup {
|
||
|
#define UI_SET_LEDBIT _IOW(UINPUT_IOCTL_BASE, 105, int)
|
||
|
#define UI_SET_SNDBIT _IOW(UINPUT_IOCTL_BASE, 106, int)
|
||
|
#define UI_SET_FFBIT _IOW(UINPUT_IOCTL_BASE, 107, int)
|
||
|
+
|
||
|
+/* DEPRECATED: Data size is ambiguous. Use UI_SET_PHYS_STR instead. */
|
||
|
#define UI_SET_PHYS _IOW(UINPUT_IOCTL_BASE, 108, char*)
|
||
|
+
|
||
|
#define UI_SET_SWBIT _IOW(UINPUT_IOCTL_BASE, 109, int)
|
||
|
#define UI_SET_PROPBIT _IOW(UINPUT_IOCTL_BASE, 110, int)
|
||
|
+#define UI_SET_PHYS_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 111, len)
|
||
|
+#define UI_SET_UNIQ_STR(len) _IOC(_IOC_WRITE, UINPUT_IOCTL_BASE, 112, len)
|
||
|
|
||
|
#define UI_BEGIN_FF_UPLOAD _IOWR(UINPUT_IOCTL_BASE, 200, struct uinput_ff_upload)
|
||
|
#define UI_END_FF_UPLOAD _IOW(UINPUT_IOCTL_BASE, 201, struct uinput_ff_upload)
|