diff options
| author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-02 00:09:51 -0500 |
|---|---|---|
| committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-02 00:09:51 -0500 |
| commit | ac648a6a704f73cc2a0f128d9deeb57aa6d76f6d (patch) | |
| tree | a0d1526755bd1ed3f5ebd042c5678fde6415760f | |
| parent | 969b21cdeee3d1561bd2b56504fa8388c5b437ff (diff) | |
Input: make modalias code respect allowed buffer size
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
| -rw-r--r-- | drivers/input/input.c | 110 |
1 files changed, 71 insertions, 39 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index db52ba0a316f..a935abeffffc 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
| @@ -571,15 +571,16 @@ INPUT_DEV_STRING_ATTR_SHOW(name); | |||
| 571 | INPUT_DEV_STRING_ATTR_SHOW(phys); | 571 | INPUT_DEV_STRING_ATTR_SHOW(phys); |
| 572 | INPUT_DEV_STRING_ATTR_SHOW(uniq); | 572 | INPUT_DEV_STRING_ATTR_SHOW(uniq); |
| 573 | 573 | ||
| 574 | static int print_modalias_bits(char *buf, int size, char prefix, unsigned long *arr, | 574 | static int input_print_modalias_bits(char *buf, int size, |
| 575 | unsigned int min, unsigned int max) | 575 | char name, unsigned long *bm, |
| 576 | unsigned int min_bit, unsigned int max_bit) | ||
| 576 | { | 577 | { |
| 577 | int len, i; | 578 | int len = 0, i; |
| 578 | 579 | ||
| 579 | len = snprintf(buf, size, "%c", prefix); | 580 | len += snprintf(buf, max(size, 0), "%c", name); |
| 580 | for (i = min; i < max; i++) | 581 | for (i = min_bit; i < max_bit; i++) |
| 581 | if (arr[LONG(i)] & BIT(i)) | 582 | if (bm[LONG(i)] & BIT(i)) |
| 582 | len += snprintf(buf + len, size - len, "%X,", i); | 583 | len += snprintf(buf + len, max(size - len, 0), "%X,", i); |
| 583 | return len; | 584 | return len; |
| 584 | } | 585 | } |
| 585 | 586 | ||
| @@ -588,33 +589,32 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id, | |||
| 588 | { | 589 | { |
| 589 | int len; | 590 | int len; |
| 590 | 591 | ||
| 591 | len = snprintf(buf, size, "input:b%04Xv%04Xp%04Xe%04X-", | 592 | len = snprintf(buf, max(size, 0), |
| 592 | id->id.bustype, | 593 | "input:b%04Xv%04Xp%04Xe%04X-", |
| 593 | id->id.vendor, | 594 | id->id.bustype, id->id.vendor, |
| 594 | id->id.product, | 595 | id->id.product, id->id.version); |
| 595 | id->id.version); | 596 | |
| 596 | 597 | len += input_print_modalias_bits(buf + len, size - len, | |
| 597 | len += print_modalias_bits(buf + len, size - len, 'e', id->evbit, | 598 | 'e', id->evbit, 0, EV_MAX); |
| 598 | 0, EV_MAX); | 599 | len += input_print_modalias_bits(buf + len, size - len, |
| 599 | len += print_modalias_bits(buf + len, size - len, 'k', id->keybit, | 600 | 'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX); |
| 600 | KEY_MIN_INTERESTING, KEY_MAX); | 601 | len += input_print_modalias_bits(buf + len, size - len, |
| 601 | len += print_modalias_bits(buf + len, size - len, 'r', id->relbit, | 602 | 'r', id->relbit, 0, REL_MAX); |
| 602 | 0, REL_MAX); | 603 | len += input_print_modalias_bits(buf + len, size - len, |
| 603 | len += print_modalias_bits(buf + len, size - len, 'a', id->absbit, | 604 | 'a', id->absbit, 0, ABS_MAX); |
| 604 | 0, ABS_MAX); | 605 | len += input_print_modalias_bits(buf + len, size - len, |
| 605 | len += print_modalias_bits(buf + len, size - len, 'm', id->mscbit, | 606 | 'm', id->mscbit, 0, MSC_MAX); |
| 606 | 0, MSC_MAX); | 607 | len += input_print_modalias_bits(buf + len, size - len, |
| 607 | len += print_modalias_bits(buf + len, size - len, 'l', id->ledbit, | 608 | 'l', id->ledbit, 0, LED_MAX); |
| 608 | 0, LED_MAX); | 609 | len += input_print_modalias_bits(buf + len, size - len, |
| 609 | len += print_modalias_bits(buf + len, size - len, 's', id->sndbit, | 610 | 's', id->sndbit, 0, SND_MAX); |
| 610 | 0, SND_MAX); | 611 | len += input_print_modalias_bits(buf + len, size - len, |
| 611 | len += print_modalias_bits(buf + len, size - len, 'f', id->ffbit, | 612 | 'f', id->ffbit, 0, FF_MAX); |
| 612 | 0, FF_MAX); | 613 | len += input_print_modalias_bits(buf + len, size - len, |
| 613 | len += print_modalias_bits(buf + len, size - len, 'w', id->swbit, | 614 | 'w', id->swbit, 0, SW_MAX); |
| 614 | 0, SW_MAX); | ||
| 615 | 615 | ||
| 616 | if (add_cr) | 616 | if (add_cr) |
| 617 | len += snprintf(buf + len, size - len, "\n"); | 617 | len += snprintf(buf + len, max(size - len, 0), "\n"); |
| 618 | 618 | ||
| 619 | return len; | 619 | return len; |
| 620 | } | 620 | } |
| @@ -739,8 +739,8 @@ static void input_dev_release(struct class_device *class_dev) | |||
| 739 | * device bitfields. | 739 | * device bitfields. |
| 740 | */ | 740 | */ |
| 741 | static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | 741 | static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, |
| 742 | char *buffer, int buffer_size, int *cur_len, | 742 | char *buffer, int buffer_size, int *cur_len, |
| 743 | const char *name, unsigned long *bitmap, int max) | 743 | const char *name, unsigned long *bitmap, int max) |
| 744 | { | 744 | { |
| 745 | if (*cur_index >= num_envp - 1) | 745 | if (*cur_index >= num_envp - 1) |
| 746 | return -ENOMEM; | 746 | return -ENOMEM; |
| @@ -748,7 +748,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | |||
| 748 | envp[*cur_index] = buffer + *cur_len; | 748 | envp[*cur_index] = buffer + *cur_len; |
| 749 | 749 | ||
| 750 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); | 750 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name); |
| 751 | if (*cur_len > buffer_size) | 751 | if (*cur_len >= buffer_size) |
| 752 | return -ENOMEM; | 752 | return -ENOMEM; |
| 753 | 753 | ||
| 754 | *cur_len += input_print_bitmap(buffer + *cur_len, | 754 | *cur_len += input_print_bitmap(buffer + *cur_len, |
| @@ -761,9 +761,33 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | |||
| 761 | return 0; | 761 | return 0; |
| 762 | } | 762 | } |
| 763 | 763 | ||
| 764 | static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index, | ||
| 765 | char *buffer, int buffer_size, int *cur_len, | ||
| 766 | struct input_dev *dev) | ||
| 767 | { | ||
| 768 | if (*cur_index >= num_envp - 1) | ||
| 769 | return -ENOMEM; | ||
| 770 | |||
| 771 | envp[*cur_index] = buffer + *cur_len; | ||
| 772 | |||
| 773 | *cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), | ||
| 774 | "MODALIAS="); | ||
| 775 | if (*cur_len >= buffer_size) | ||
| 776 | return -ENOMEM; | ||
| 777 | |||
| 778 | *cur_len += input_print_modalias(buffer + *cur_len, | ||
| 779 | max(buffer_size - *cur_len, 0), | ||
| 780 | dev, 0) + 1; | ||
| 781 | if (*cur_len > buffer_size) | ||
| 782 | return -ENOMEM; | ||
| 783 | |||
| 784 | (*cur_index)++; | ||
| 785 | return 0; | ||
| 786 | } | ||
| 787 | |||
| 764 | #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ | 788 | #define INPUT_ADD_HOTPLUG_VAR(fmt, val...) \ |
| 765 | do { \ | 789 | do { \ |
| 766 | int err = add_uevent_var(envp, num_envp, &i, \ | 790 | int err = add_uevent_var(envp, num_envp, &i, \ |
| 767 | buffer, buffer_size, &len, \ | 791 | buffer, buffer_size, &len, \ |
| 768 | fmt, val); \ | 792 | fmt, val); \ |
| 769 | if (err) \ | 793 | if (err) \ |
| @@ -779,6 +803,16 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | |||
| 779 | return err; \ | 803 | return err; \ |
| 780 | } while (0) | 804 | } while (0) |
| 781 | 805 | ||
| 806 | #define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev) \ | ||
| 807 | do { \ | ||
| 808 | int err = input_add_uevent_modalias_var(envp, \ | ||
| 809 | num_envp, &i, \ | ||
| 810 | buffer, buffer_size, &len, \ | ||
| 811 | dev); \ | ||
| 812 | if (err) \ | ||
| 813 | return err; \ | ||
| 814 | } while (0) | ||
| 815 | |||
| 782 | static int input_dev_uevent(struct class_device *cdev, char **envp, | 816 | static int input_dev_uevent(struct class_device *cdev, char **envp, |
| 783 | int num_envp, char *buffer, int buffer_size) | 817 | int num_envp, char *buffer, int buffer_size) |
| 784 | { | 818 | { |
| @@ -814,9 +848,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp, | |||
| 814 | if (test_bit(EV_SW, dev->evbit)) | 848 | if (test_bit(EV_SW, dev->evbit)) |
| 815 | INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX); | 849 | INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX); |
| 816 | 850 | ||
| 817 | envp[i++] = buffer + len; | 851 | INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev); |
| 818 | len += snprintf(buffer + len, buffer_size - len, "MODALIAS="); | ||
| 819 | len += input_print_modalias(buffer + len, buffer_size - len, dev, 0) + 1; | ||
| 820 | 852 | ||
| 821 | envp[i] = NULL; | 853 | envp[i] = NULL; |
| 822 | return 0; | 854 | return 0; |
