Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Input: uinput - add new UINPUT_DEV_SETUP and UI_ABS_SETUP ioctl

This adds two new ioctls, UINPUT_DEV_SETUP and UI_ABS_SETUP, that replaces
the old device setup method (by write()'ing "struct uinput_user_dev" to the
node). The old method is not easily extendable and requires huge payloads.
Furthermore, overloading write() without properly versioned objects is
error-prone.

Therefore, we introduce two new ioctls to replace the old method. These
ioctls support all features of the old method, plus a "resolution" field
for absinfo. Furthermore, it's properly forward-compatible to new ABS codes
and a growing "struct input_absinfo" structure.

UI_ABS_SETUP also allows user-space to skip unknown axes if not set. There
is no need to copy the whole array temporarily into the kernel, but instead
the caller issues several ioctl where we copy each value manually.

Signed-off-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Benjamin Tissoires <benjamin.tissoires@redhat.com>
Reviewed-by: David Herrmann <dh.herrmann@gmail.com>
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>

authored by

Benjamin Tissoires and committed by
Dmitry Torokhov
052876f8 f01c5e65

+168 -6
+83 -3
drivers/input/misc/uinput.c
··· 370 370 return 0; 371 371 } 372 372 373 - static int uinput_setup_device(struct uinput_device *udev, 374 - const char __user *buffer, size_t count) 373 + static int uinput_dev_setup(struct uinput_device *udev, 374 + struct uinput_setup __user *arg) 375 + { 376 + struct uinput_setup setup; 377 + struct input_dev *dev; 378 + int retval; 379 + 380 + if (udev->state == UIST_CREATED) 381 + return -EINVAL; 382 + 383 + if (copy_from_user(&setup, arg, sizeof(setup))) 384 + return -EFAULT; 385 + 386 + if (!setup.name[0]) 387 + return -EINVAL; 388 + 389 + dev = udev->dev; 390 + dev->id = setup.id; 391 + udev->ff_effects_max = setup.ff_effects_max; 392 + 393 + kfree(dev->name); 394 + dev->name = kstrndup(setup.name, UINPUT_MAX_NAME_SIZE, GFP_KERNEL); 395 + if (!dev->name) 396 + return -ENOMEM; 397 + 398 + retval = uinput_validate_absbits(dev); 399 + if (retval < 0) 400 + return retval; 401 + 402 + udev->state = UIST_SETUP_COMPLETE; 403 + return 0; 404 + } 405 + 406 + static int uinput_abs_setup(struct uinput_device *udev, 407 + struct uinput_setup __user *arg, size_t size) 408 + { 409 + struct uinput_abs_setup setup = {}; 410 + struct input_dev *dev; 411 + 412 + if (size > sizeof(setup)) 413 + return -E2BIG; 414 + 415 + if (udev->state == UIST_CREATED) 416 + return -EINVAL; 417 + 418 + if (copy_from_user(&setup, arg, size)) 419 + return -EFAULT; 420 + 421 + if (setup.code > ABS_MAX) 422 + return -ERANGE; 423 + 424 + dev = udev->dev; 425 + 426 + input_alloc_absinfo(dev); 427 + if (!dev->absinfo) 428 + return -ENOMEM; 429 + 430 + set_bit(setup.code, dev->absbit); 431 + dev->absinfo[setup.code] = setup.absinfo; 432 + 433 + /* 434 + * We restore the state to UIST_NEW_DEVICE because the user has to call 435 + * UI_DEV_SETUP in the last place before UI_DEV_CREATE to check the 436 + * validity of the absbits. 437 + */ 438 + udev->state = UIST_NEW_DEVICE; 439 + return 0; 440 + } 441 + 442 + /* legacy setup via write() */ 443 + static int uinput_setup_device_legacy(struct uinput_device *udev, 444 + const char __user *buffer, size_t count) 375 445 { 376 446 struct uinput_user_dev *user_dev; 377 447 struct input_dev *dev; ··· 544 474 545 475 retval = udev->state == UIST_CREATED ? 546 476 uinput_inject_events(udev, buffer, count) : 547 - uinput_setup_device(udev, buffer, count); 477 + uinput_setup_device_legacy(udev, buffer, count); 548 478 549 479 mutex_unlock(&udev->mutex); 550 480 ··· 805 735 uinput_destroy_device(udev); 806 736 goto out; 807 737 738 + case UI_DEV_SETUP: 739 + retval = uinput_dev_setup(udev, p); 740 + goto out; 741 + 742 + /* UI_ABS_SETUP is handled in the variable size ioctls */ 743 + 808 744 case UI_SET_EVBIT: 809 745 retval = uinput_set_bit(arg, evbit, EV_MAX); 810 746 goto out; ··· 954 878 } 955 879 name = dev_name(&udev->dev->dev); 956 880 retval = uinput_str_to_user(p, name, size); 881 + goto out; 882 + 883 + case UI_ABS_SETUP & ~IOCSIZE_MASK: 884 + retval = uinput_abs_setup(udev, p, size); 957 885 goto out; 958 886 } 959 887
+5
include/linux/uinput.h
··· 20 20 * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org> 21 21 * 22 22 * Changes/Revisions: 23 + * 0.5 08/13/2015 (David Herrmann <dh.herrmann@gmail.com> & 24 + * Benjamin Tissoires <benjamin.tissoires@redhat.com>) 25 + * - add UI_DEV_SETUP ioctl 26 + * - add UI_ABS_SETUP ioctl 27 + * - add UI_GET_VERSION ioctl 23 28 * 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>) 24 29 * - add UI_GET_SYSNAME ioctl 25 30 * 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>)
+80 -3
include/uapi/linux/uinput.h
··· 20 20 * Author: Aristeu Sergio Rozanski Filho <aris@cathedrallabs.org> 21 21 * 22 22 * Changes/Revisions: 23 + * 0.5 08/13/2015 (David Herrmann <dh.herrmann@gmail.com> & 24 + * Benjamin Tissoires <benjamin.tissoires@redhat.com>) 25 + * - add UI_DEV_SETUP ioctl 26 + * - add UI_ABS_SETUP ioctl 27 + * - add UI_GET_VERSION ioctl 23 28 * 0.4 01/09/2014 (Benjamin Tissoires <benjamin.tissoires@redhat.com>) 24 29 * - add UI_GET_SYSNAME ioctl 25 30 * 0.3 24/05/2006 (Anssi Hannula <anssi.hannulagmail.com>) ··· 42 37 #include <linux/types.h> 43 38 #include <linux/input.h> 44 39 45 - #define UINPUT_VERSION 4 46 - 40 + #define UINPUT_VERSION 5 41 + #define UINPUT_MAX_NAME_SIZE 80 47 42 48 43 struct uinput_ff_upload { 49 44 __u32 request_id; ··· 62 57 #define UINPUT_IOCTL_BASE 'U' 63 58 #define UI_DEV_CREATE _IO(UINPUT_IOCTL_BASE, 1) 64 59 #define UI_DEV_DESTROY _IO(UINPUT_IOCTL_BASE, 2) 60 + 61 + struct uinput_setup { 62 + struct input_id id; 63 + char name[UINPUT_MAX_NAME_SIZE]; 64 + __u32 ff_effects_max; 65 + }; 66 + 67 + /** 68 + * UI_DEV_SETUP - Set device parameters for setup 69 + * 70 + * This ioctl sets parameters for the input device to be created. It must be 71 + * issued *before* calling UI_DEV_CREATE or it will fail. This ioctl supersedes 72 + * the old "struct uinput_user_dev" method, which wrote this data via write(). 73 + * To actually set the absolute axes, you also need to call the ioctl 74 + * UI_ABS_SETUP *before* calling this ioctl. 75 + * 76 + * This ioctl takes a "struct uinput_setup" object as argument. The fields of 77 + * this object are as follows: 78 + * id: See the description of "struct input_id". This field is 79 + * copied unchanged into the new device. 80 + * name: This is used unchanged as name for the new device. 81 + * ff_effects_max: This limits the maximum numbers of force-feedback effects. 82 + * See below for a description of FF with uinput. 83 + * 84 + * This ioctl can be called multiple times and will overwrite previous values. 85 + * If this ioctl fails with -EINVAL, you're recommended to use the old 86 + * "uinput_user_dev" method via write() as fallback, in case you run on an old 87 + * kernel that does not support this ioctl. 88 + * 89 + * This ioctl may fail with -EINVAL if it is not supported or if you passed 90 + * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the 91 + * passed uinput_setup object cannot be read/written. 92 + * If this call fails, partial data may have already been applied to the 93 + * internal device. 94 + */ 95 + #define UI_DEV_SETUP _IOW(UINPUT_IOCTL_BASE, 3, struct uinput_setup) 96 + 97 + struct uinput_abs_setup { 98 + __u16 code; /* axis code */ 99 + /* __u16 filler; */ 100 + struct input_absinfo absinfo; 101 + }; 102 + 103 + /** 104 + * UI_ABS_SETUP - Set absolute axis information for the device to setup 105 + * 106 + * This ioctl sets one absolute axis information for the input device to be 107 + * created. It must be issued *before* calling UI_DEV_SETUP and UI_DEV_CREATE 108 + * for every absolute axis the device exports. 109 + * This ioctl supersedes the old "struct uinput_user_dev" method, which wrote 110 + * part of this data and the content of UI_DEV_SETUP via write(). 111 + * 112 + * This ioctl takes a "struct uinput_abs_setup" object as argument. The fields 113 + * of this object are as follows: 114 + * code: The corresponding input code associated with this axis 115 + * (ABS_X, ABS_Y, etc...) 116 + * absinfo: See "struct input_absinfo" for a description of this field. 117 + * This field is copied unchanged into the kernel for the 118 + * specified axis. If the axis is not enabled via 119 + * UI_SET_ABSBIT, this ioctl will enable it. 120 + * 121 + * This ioctl can be called multiple times and will overwrite previous values. 122 + * If this ioctl fails with -EINVAL, you're recommended to use the old 123 + * "uinput_user_dev" method via write() as fallback, in case you run on an old 124 + * kernel that does not support this ioctl. 125 + * 126 + * This ioctl may fail with -EINVAL if it is not supported or if you passed 127 + * incorrect values, -ENOMEM if the kernel runs out of memory or -EFAULT if the 128 + * passed uinput_setup object cannot be read/written. 129 + * If this call fails, partial data may have already been applied to the 130 + * internal device. 131 + */ 132 + #define UI_ABS_SETUP _IOW(UINPUT_IOCTL_BASE, 4, struct uinput_abs_setup) 65 133 66 134 #define UI_SET_EVBIT _IOW(UINPUT_IOCTL_BASE, 100, int) 67 135 #define UI_SET_KEYBIT _IOW(UINPUT_IOCTL_BASE, 101, int) ··· 222 144 #define UI_FF_UPLOAD 1 223 145 #define UI_FF_ERASE 2 224 146 225 - #define UINPUT_MAX_NAME_SIZE 80 226 147 struct uinput_user_dev { 227 148 char name[UINPUT_MAX_NAME_SIZE]; 228 149 struct input_id id;