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 /drivers/input | |
parent | 969b21cdeee3d1561bd2b56504fa8388c5b437ff (diff) |
Input: make modalias code respect allowed buffer size
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
Diffstat (limited to 'drivers/input')
-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; |