diff options
Diffstat (limited to 'drivers/input/evdev.c')
-rw-r--r-- | drivers/input/evdev.c | 175 |
1 files changed, 97 insertions, 78 deletions
diff --git a/drivers/input/evdev.c b/drivers/input/evdev.c index e3f7fc6f9565..88d8e4cb419a 100644 --- a/drivers/input/evdev.c +++ b/drivers/input/evdev.c | |||
@@ -8,6 +8,8 @@ | |||
8 | * the Free Software Foundation. | 8 | * the Free Software Foundation. |
9 | */ | 9 | */ |
10 | 10 | ||
11 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt | ||
12 | |||
11 | #define EVDEV_MINOR_BASE 64 | 13 | #define EVDEV_MINOR_BASE 64 |
12 | #define EVDEV_MINORS 32 | 14 | #define EVDEV_MINORS 32 |
13 | #define EVDEV_MIN_BUFFER_SIZE 64U | 15 | #define EVDEV_MIN_BUFFER_SIZE 64U |
@@ -37,13 +39,13 @@ struct evdev { | |||
37 | }; | 39 | }; |
38 | 40 | ||
39 | struct evdev_client { | 41 | struct evdev_client { |
40 | int head; | 42 | unsigned int head; |
41 | int tail; | 43 | unsigned int tail; |
42 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ | 44 | spinlock_t buffer_lock; /* protects access to buffer, head and tail */ |
43 | struct fasync_struct *fasync; | 45 | struct fasync_struct *fasync; |
44 | struct evdev *evdev; | 46 | struct evdev *evdev; |
45 | struct list_head node; | 47 | struct list_head node; |
46 | int bufsize; | 48 | unsigned int bufsize; |
47 | struct input_event buffer[]; | 49 | struct input_event buffer[]; |
48 | }; | 50 | }; |
49 | 51 | ||
@@ -53,16 +55,25 @@ static DEFINE_MUTEX(evdev_table_mutex); | |||
53 | static void evdev_pass_event(struct evdev_client *client, | 55 | static void evdev_pass_event(struct evdev_client *client, |
54 | struct input_event *event) | 56 | struct input_event *event) |
55 | { | 57 | { |
56 | /* | 58 | /* Interrupts are disabled, just acquire the lock. */ |
57 | * Interrupts are disabled, just acquire the lock. | ||
58 | * Make sure we don't leave with the client buffer | ||
59 | * "empty" by having client->head == client->tail. | ||
60 | */ | ||
61 | spin_lock(&client->buffer_lock); | 59 | spin_lock(&client->buffer_lock); |
62 | do { | 60 | |
63 | client->buffer[client->head++] = *event; | 61 | client->buffer[client->head++] = *event; |
64 | client->head &= client->bufsize - 1; | 62 | client->head &= client->bufsize - 1; |
65 | } while (client->head == client->tail); | 63 | |
64 | if (unlikely(client->head == client->tail)) { | ||
65 | /* | ||
66 | * This effectively "drops" all unconsumed events, leaving | ||
67 | * EV_SYN/SYN_DROPPED plus the newest event in the queue. | ||
68 | */ | ||
69 | client->tail = (client->head - 2) & (client->bufsize - 1); | ||
70 | |||
71 | client->buffer[client->tail].time = event->time; | ||
72 | client->buffer[client->tail].type = EV_SYN; | ||
73 | client->buffer[client->tail].code = SYN_DROPPED; | ||
74 | client->buffer[client->tail].value = 0; | ||
75 | } | ||
76 | |||
66 | spin_unlock(&client->buffer_lock); | 77 | spin_unlock(&client->buffer_lock); |
67 | 78 | ||
68 | if (event->type == EV_SYN) | 79 | if (event->type == EV_SYN) |
@@ -319,6 +330,9 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
319 | struct input_event event; | 330 | struct input_event event; |
320 | int retval; | 331 | int retval; |
321 | 332 | ||
333 | if (count < input_event_size()) | ||
334 | return -EINVAL; | ||
335 | |||
322 | retval = mutex_lock_interruptible(&evdev->mutex); | 336 | retval = mutex_lock_interruptible(&evdev->mutex); |
323 | if (retval) | 337 | if (retval) |
324 | return retval; | 338 | return retval; |
@@ -328,17 +342,16 @@ static ssize_t evdev_write(struct file *file, const char __user *buffer, | |||
328 | goto out; | 342 | goto out; |
329 | } | 343 | } |
330 | 344 | ||
331 | while (retval < count) { | 345 | do { |
332 | |||
333 | if (input_event_from_user(buffer + retval, &event)) { | 346 | if (input_event_from_user(buffer + retval, &event)) { |
334 | retval = -EFAULT; | 347 | retval = -EFAULT; |
335 | goto out; | 348 | goto out; |
336 | } | 349 | } |
350 | retval += input_event_size(); | ||
337 | 351 | ||
338 | input_inject_event(&evdev->handle, | 352 | input_inject_event(&evdev->handle, |
339 | event.type, event.code, event.value); | 353 | event.type, event.code, event.value); |
340 | retval += input_event_size(); | 354 | } while (retval + input_event_size() <= count); |
341 | } | ||
342 | 355 | ||
343 | out: | 356 | out: |
344 | mutex_unlock(&evdev->mutex); | 357 | mutex_unlock(&evdev->mutex); |
@@ -522,88 +535,84 @@ static int handle_eviocgbit(struct input_dev *dev, | |||
522 | if (type == EV_KEY && size == OLD_KEY_MAX) { | 535 | if (type == EV_KEY && size == OLD_KEY_MAX) { |
523 | len = OLD_KEY_MAX; | 536 | len = OLD_KEY_MAX; |
524 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) | 537 | if (printk_timed_ratelimit(&keymax_warn_time, 10 * 1000)) |
525 | printk(KERN_WARNING | 538 | pr_warning("(EVIOCGBIT): Suspicious buffer size %u, " |
526 | "evdev.c(EVIOCGBIT): Suspicious buffer size %u, " | 539 | "limiting output to %zu bytes. See " |
527 | "limiting output to %zu bytes. See " | 540 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", |
528 | "http://userweb.kernel.org/~dtor/eviocgbit-bug.html\n", | 541 | OLD_KEY_MAX, |
529 | OLD_KEY_MAX, | 542 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); |
530 | BITS_TO_LONGS(OLD_KEY_MAX) * sizeof(long)); | ||
531 | } | 543 | } |
532 | 544 | ||
533 | return bits_to_user(bits, len, size, p, compat_mode); | 545 | return bits_to_user(bits, len, size, p, compat_mode); |
534 | } | 546 | } |
535 | #undef OLD_KEY_MAX | 547 | #undef OLD_KEY_MAX |
536 | 548 | ||
537 | static int evdev_handle_get_keycode(struct input_dev *dev, | 549 | static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p) |
538 | void __user *p, size_t size) | ||
539 | { | 550 | { |
540 | struct input_keymap_entry ke; | 551 | struct input_keymap_entry ke = { |
552 | .len = sizeof(unsigned int), | ||
553 | .flags = 0, | ||
554 | }; | ||
555 | int __user *ip = (int __user *)p; | ||
541 | int error; | 556 | int error; |
542 | 557 | ||
543 | memset(&ke, 0, sizeof(ke)); | 558 | /* legacy case */ |
544 | 559 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | |
545 | if (size == sizeof(unsigned int[2])) { | 560 | return -EFAULT; |
546 | /* legacy case */ | ||
547 | int __user *ip = (int __user *)p; | ||
548 | 561 | ||
549 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 562 | error = input_get_keycode(dev, &ke); |
550 | return -EFAULT; | 563 | if (error) |
564 | return error; | ||
551 | 565 | ||
552 | ke.len = sizeof(unsigned int); | 566 | if (put_user(ke.keycode, ip + 1)) |
553 | ke.flags = 0; | 567 | return -EFAULT; |
554 | 568 | ||
555 | error = input_get_keycode(dev, &ke); | 569 | return 0; |
556 | if (error) | 570 | } |
557 | return error; | ||
558 | 571 | ||
559 | if (put_user(ke.keycode, ip + 1)) | 572 | static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p) |
560 | return -EFAULT; | 573 | { |
574 | struct input_keymap_entry ke; | ||
575 | int error; | ||
561 | 576 | ||
562 | } else { | 577 | if (copy_from_user(&ke, p, sizeof(ke))) |
563 | size = min(size, sizeof(ke)); | 578 | return -EFAULT; |
564 | 579 | ||
565 | if (copy_from_user(&ke, p, size)) | 580 | error = input_get_keycode(dev, &ke); |
566 | return -EFAULT; | 581 | if (error) |
582 | return error; | ||
567 | 583 | ||
568 | error = input_get_keycode(dev, &ke); | 584 | if (copy_to_user(p, &ke, sizeof(ke))) |
569 | if (error) | 585 | return -EFAULT; |
570 | return error; | ||
571 | 586 | ||
572 | if (copy_to_user(p, &ke, size)) | ||
573 | return -EFAULT; | ||
574 | } | ||
575 | return 0; | 587 | return 0; |
576 | } | 588 | } |
577 | 589 | ||
578 | static int evdev_handle_set_keycode(struct input_dev *dev, | 590 | static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p) |
579 | void __user *p, size_t size) | ||
580 | { | 591 | { |
581 | struct input_keymap_entry ke; | 592 | struct input_keymap_entry ke = { |
582 | 593 | .len = sizeof(unsigned int), | |
583 | memset(&ke, 0, sizeof(ke)); | 594 | .flags = 0, |
595 | }; | ||
596 | int __user *ip = (int __user *)p; | ||
584 | 597 | ||
585 | if (size == sizeof(unsigned int[2])) { | 598 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) |
586 | /* legacy case */ | 599 | return -EFAULT; |
587 | int __user *ip = (int __user *)p; | ||
588 | 600 | ||
589 | if (copy_from_user(ke.scancode, p, sizeof(unsigned int))) | 601 | if (get_user(ke.keycode, ip + 1)) |
590 | return -EFAULT; | 602 | return -EFAULT; |
591 | 603 | ||
592 | if (get_user(ke.keycode, ip + 1)) | 604 | return input_set_keycode(dev, &ke); |
593 | return -EFAULT; | 605 | } |
594 | |||
595 | ke.len = sizeof(unsigned int); | ||
596 | ke.flags = 0; | ||
597 | 606 | ||
598 | } else { | 607 | static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p) |
599 | size = min(size, sizeof(ke)); | 608 | { |
609 | struct input_keymap_entry ke; | ||
600 | 610 | ||
601 | if (copy_from_user(&ke, p, size)) | 611 | if (copy_from_user(&ke, p, sizeof(ke))) |
602 | return -EFAULT; | 612 | return -EFAULT; |
603 | 613 | ||
604 | if (ke.len > sizeof(ke.scancode)) | 614 | if (ke.len > sizeof(ke.scancode)) |
605 | return -EINVAL; | 615 | return -EINVAL; |
606 | } | ||
607 | 616 | ||
608 | return input_set_keycode(dev, &ke); | 617 | return input_set_keycode(dev, &ke); |
609 | } | 618 | } |
@@ -669,6 +678,18 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
669 | return evdev_grab(evdev, client); | 678 | return evdev_grab(evdev, client); |
670 | else | 679 | else |
671 | return evdev_ungrab(evdev, client); | 680 | return evdev_ungrab(evdev, client); |
681 | |||
682 | case EVIOCGKEYCODE: | ||
683 | return evdev_handle_get_keycode(dev, p); | ||
684 | |||
685 | case EVIOCSKEYCODE: | ||
686 | return evdev_handle_set_keycode(dev, p); | ||
687 | |||
688 | case EVIOCGKEYCODE_V2: | ||
689 | return evdev_handle_get_keycode_v2(dev, p); | ||
690 | |||
691 | case EVIOCSKEYCODE_V2: | ||
692 | return evdev_handle_set_keycode_v2(dev, p); | ||
672 | } | 693 | } |
673 | 694 | ||
674 | size = _IOC_SIZE(cmd); | 695 | size = _IOC_SIZE(cmd); |
@@ -677,6 +698,10 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
677 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) | 698 | #define EVIOC_MASK_SIZE(nr) ((nr) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT)) |
678 | switch (EVIOC_MASK_SIZE(cmd)) { | 699 | switch (EVIOC_MASK_SIZE(cmd)) { |
679 | 700 | ||
701 | case EVIOCGPROP(0): | ||
702 | return bits_to_user(dev->propbit, INPUT_PROP_MAX, | ||
703 | size, p, compat_mode); | ||
704 | |||
680 | case EVIOCGKEY(0): | 705 | case EVIOCGKEY(0): |
681 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); | 706 | return bits_to_user(dev->key, KEY_MAX, size, p, compat_mode); |
682 | 707 | ||
@@ -708,12 +733,6 @@ static long evdev_do_ioctl(struct file *file, unsigned int cmd, | |||
708 | return -EFAULT; | 733 | return -EFAULT; |
709 | 734 | ||
710 | return error; | 735 | return error; |
711 | |||
712 | case EVIOC_MASK_SIZE(EVIOCGKEYCODE): | ||
713 | return evdev_handle_get_keycode(dev, p, size); | ||
714 | |||
715 | case EVIOC_MASK_SIZE(EVIOCSKEYCODE): | ||
716 | return evdev_handle_set_keycode(dev, p, size); | ||
717 | } | 736 | } |
718 | 737 | ||
719 | /* Multi-number variable-length handlers */ | 738 | /* Multi-number variable-length handlers */ |
@@ -894,7 +913,7 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev, | |||
894 | break; | 913 | break; |
895 | 914 | ||
896 | if (minor == EVDEV_MINORS) { | 915 | if (minor == EVDEV_MINORS) { |
897 | printk(KERN_ERR "evdev: no more free evdev devices\n"); | 916 | pr_err("no more free evdev devices\n"); |
898 | return -ENFILE; | 917 | return -ENFILE; |
899 | } | 918 | } |
900 | 919 | ||