diff options
author | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-02 00:09:26 -0500 |
---|---|---|
committer | Dmitry Torokhov <dtor_core@ameritech.net> | 2006-04-02 00:09:26 -0500 |
commit | 2db66876334d6bf44414cb6225d134b751b1d7ff (patch) | |
tree | a02d1734d24df2bb7a89e8190577204d43b2385f | |
parent | 95d465fd750897ab32462a6702fbfe1b122cbbc0 (diff) |
Input: limit attributes' output to PAGE_SIZE
sysfs can't handle more than PAGE_SIZE data coming from attributes'
show() methods; make sure we respect this limit.
Signed-off-by: Dmitry Torokhov <dtor@mail.ru>
-rw-r--r-- | drivers/input/input.c | 36 |
1 files changed, 24 insertions, 12 deletions
diff --git a/drivers/input/input.c b/drivers/input/input.c index de94ffcb0995..8dcd3931fa62 100644 --- a/drivers/input/input.c +++ b/drivers/input/input.c | |||
@@ -316,7 +316,8 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st | |||
316 | return NULL; | 316 | return NULL; |
317 | } | 317 | } |
318 | 318 | ||
319 | static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max) | 319 | static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, |
320 | int max, int add_cr) | ||
320 | { | 321 | { |
321 | int i; | 322 | int i; |
322 | int len = 0; | 323 | int len = 0; |
@@ -328,6 +329,10 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, in | |||
328 | for (; i >= 0; i--) | 329 | for (; i >= 0; i--) |
329 | len += snprintf(buf + len, max(buf_size - len, 0), | 330 | len += snprintf(buf + len, max(buf_size - len, 0), |
330 | "%lx%s", bitmap[i], i > 0 ? " " : ""); | 331 | "%lx%s", bitmap[i], i > 0 ? " " : ""); |
332 | |||
333 | if (add_cr) | ||
334 | len += snprintf(buf + len, max(buf_size - len, 0), "\n"); | ||
335 | |||
331 | return len; | 336 | return len; |
332 | } | 337 | } |
333 | 338 | ||
@@ -356,8 +361,7 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait) | |||
356 | do { \ | 361 | do { \ |
357 | len += sprintf(buf + len, "B: %s=", #ev); \ | 362 | len += sprintf(buf + len, "B: %s=", #ev); \ |
358 | len += input_print_bitmap(buf + len, INT_MAX, \ | 363 | len += input_print_bitmap(buf + len, INT_MAX, \ |
359 | dev->bm##bit, ev##_MAX); \ | 364 | dev->bm##bit, ev##_MAX, 1); \ |
360 | len += sprintf(buf + len, "\n"); \ | ||
361 | } while (0) | 365 | } while (0) |
362 | 366 | ||
363 | #define TEST_AND_SPRINTF_BIT(ev, bm) \ | 367 | #define TEST_AND_SPRINTF_BIT(ev, bm) \ |
@@ -517,7 +521,8 @@ static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \ | |||
517 | if (retval) \ | 521 | if (retval) \ |
518 | return retval; \ | 522 | return retval; \ |
519 | \ | 523 | \ |
520 | retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \ | 524 | retval = scnprintf(buf, PAGE_SIZE, \ |
525 | "%s\n", input_dev->name ? input_dev->name : ""); \ | ||
521 | \ | 526 | \ |
522 | mutex_unlock(&input_dev->mutex); \ | 527 | mutex_unlock(&input_dev->mutex); \ |
523 | \ | 528 | \ |
@@ -541,7 +546,8 @@ static int print_modalias_bits(char *buf, int size, char prefix, unsigned long * | |||
541 | return len; | 546 | return len; |
542 | } | 547 | } |
543 | 548 | ||
544 | static int print_modalias(char *buf, int size, struct input_dev *id) | 549 | static int input_print_modalias(char *buf, int size, struct input_dev *id, |
550 | int add_cr) | ||
545 | { | 551 | { |
546 | int len; | 552 | int len; |
547 | 553 | ||
@@ -569,6 +575,10 @@ static int print_modalias(char *buf, int size, struct input_dev *id) | |||
569 | 0, FF_MAX); | 575 | 0, FF_MAX); |
570 | len += print_modalias_bits(buf + len, size - len, 'w', id->swbit, | 576 | len += print_modalias_bits(buf + len, size - len, 'w', id->swbit, |
571 | 0, SW_MAX); | 577 | 0, SW_MAX); |
578 | |||
579 | if (add_cr) | ||
580 | len += snprintf(buf + len, size - len, "\n"); | ||
581 | |||
572 | return len; | 582 | return len; |
573 | } | 583 | } |
574 | 584 | ||
@@ -577,9 +587,9 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) | |||
577 | struct input_dev *id = to_input_dev(dev); | 587 | struct input_dev *id = to_input_dev(dev); |
578 | ssize_t len; | 588 | ssize_t len; |
579 | 589 | ||
580 | len = print_modalias(buf, PAGE_SIZE, id); | 590 | len = input_print_modalias(buf, PAGE_SIZE, id, 1); |
581 | len += snprintf(buf + len, PAGE_SIZE-len, "\n"); | 591 | |
582 | return len; | 592 | return max_t(int, len, PAGE_SIZE); |
583 | } | 593 | } |
584 | static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); | 594 | static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); |
585 | 595 | ||
@@ -599,7 +609,7 @@ static struct attribute_group input_dev_attr_group = { | |||
599 | static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ | 609 | static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ |
600 | { \ | 610 | { \ |
601 | struct input_dev *input_dev = to_input_dev(dev); \ | 611 | struct input_dev *input_dev = to_input_dev(dev); \ |
602 | return sprintf(buf, "%04x\n", input_dev->id.name); \ | 612 | return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \ |
603 | } \ | 613 | } \ |
604 | static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); | 614 | static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); |
605 | 615 | ||
@@ -625,7 +635,9 @@ static struct attribute_group input_dev_id_attr_group = { | |||
625 | static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ | 635 | static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ |
626 | { \ | 636 | { \ |
627 | struct input_dev *input_dev = to_input_dev(dev); \ | 637 | struct input_dev *input_dev = to_input_dev(dev); \ |
628 | return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\ | 638 | int len = input_print_bitmap(buf, PAGE_SIZE, \ |
639 | input_dev->bm##bit, ev##_MAX, 1); \ | ||
640 | return min_t(int, len, PAGE_SIZE); \ | ||
629 | } \ | 641 | } \ |
630 | static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); | 642 | static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); |
631 | 643 | ||
@@ -684,7 +696,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, | |||
684 | 696 | ||
685 | *cur_len += input_print_bitmap(buffer + *cur_len, | 697 | *cur_len += input_print_bitmap(buffer + *cur_len, |
686 | max(buffer_size - *cur_len, 0), | 698 | max(buffer_size - *cur_len, 0), |
687 | bitmap, max) + 1; | 699 | bitmap, max, 0) + 1; |
688 | if (*cur_len > buffer_size) | 700 | if (*cur_len > buffer_size) |
689 | return -ENOMEM; | 701 | return -ENOMEM; |
690 | 702 | ||
@@ -747,7 +759,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp, | |||
747 | 759 | ||
748 | envp[i++] = buffer + len; | 760 | envp[i++] = buffer + len; |
749 | len += snprintf(buffer + len, buffer_size - len, "MODALIAS="); | 761 | len += snprintf(buffer + len, buffer_size - len, "MODALIAS="); |
750 | len += print_modalias(buffer + len, buffer_size - len, dev) + 1; | 762 | len += input_print_modalias(buffer + len, buffer_size - len, dev, 0) + 1; |
751 | 763 | ||
752 | envp[i] = NULL; | 764 | envp[i] = NULL; |
753 | return 0; | 765 | return 0; |