Commit 2db66876 authored by Dmitry Torokhov's avatar Dmitry Torokhov

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: default avatarDmitry Torokhov <dtor@mail.ru>
parent 95d465fd
...@@ -316,7 +316,8 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st ...@@ -316,7 +316,8 @@ static struct input_device_id *input_match_device(struct input_device_id *id, st
return NULL; return NULL;
} }
static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, int max) static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap,
int max, int add_cr)
{ {
int i; int i;
int len = 0; int len = 0;
...@@ -328,6 +329,10 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, in ...@@ -328,6 +329,10 @@ static int input_print_bitmap(char *buf, int buf_size, unsigned long *bitmap, in
for (; i >= 0; i--) for (; i >= 0; i--)
len += snprintf(buf + len, max(buf_size - len, 0), len += snprintf(buf + len, max(buf_size - len, 0),
"%lx%s", bitmap[i], i > 0 ? " " : ""); "%lx%s", bitmap[i], i > 0 ? " " : "");
if (add_cr)
len += snprintf(buf + len, max(buf_size - len, 0), "\n");
return len; return len;
} }
...@@ -356,8 +361,7 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait) ...@@ -356,8 +361,7 @@ static unsigned int input_devices_poll(struct file *file, poll_table *wait)
do { \ do { \
len += sprintf(buf + len, "B: %s=", #ev); \ len += sprintf(buf + len, "B: %s=", #ev); \
len += input_print_bitmap(buf + len, INT_MAX, \ len += input_print_bitmap(buf + len, INT_MAX, \
dev->bm##bit, ev##_MAX); \ dev->bm##bit, ev##_MAX, 1); \
len += sprintf(buf + len, "\n"); \
} while (0) } while (0)
#define TEST_AND_SPRINTF_BIT(ev, bm) \ #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,7 +521,8 @@ static ssize_t input_dev_show_##name(struct class_device *dev, char *buf) \
if (retval) \ if (retval) \
return retval; \ return retval; \
\ \
retval = sprintf(buf, "%s\n", input_dev->name ? input_dev->name : ""); \ retval = scnprintf(buf, PAGE_SIZE, \
"%s\n", input_dev->name ? input_dev->name : ""); \
\ \
mutex_unlock(&input_dev->mutex); \ mutex_unlock(&input_dev->mutex); \
\ \
...@@ -541,7 +546,8 @@ static int print_modalias_bits(char *buf, int size, char prefix, unsigned long * ...@@ -541,7 +546,8 @@ static int print_modalias_bits(char *buf, int size, char prefix, unsigned long *
return len; return len;
} }
static int print_modalias(char *buf, int size, struct input_dev *id) static int input_print_modalias(char *buf, int size, struct input_dev *id,
int add_cr)
{ {
int len; int len;
...@@ -569,6 +575,10 @@ static int print_modalias(char *buf, int size, struct input_dev *id) ...@@ -569,6 +575,10 @@ static int print_modalias(char *buf, int size, struct input_dev *id)
0, FF_MAX); 0, FF_MAX);
len += print_modalias_bits(buf + len, size - len, 'w', id->swbit, len += print_modalias_bits(buf + len, size - len, 'w', id->swbit,
0, SW_MAX); 0, SW_MAX);
if (add_cr)
len += snprintf(buf + len, size - len, "\n");
return len; return len;
} }
...@@ -577,9 +587,9 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf) ...@@ -577,9 +587,9 @@ static ssize_t input_dev_show_modalias(struct class_device *dev, char *buf)
struct input_dev *id = to_input_dev(dev); struct input_dev *id = to_input_dev(dev);
ssize_t len; ssize_t len;
len = print_modalias(buf, PAGE_SIZE, id); len = input_print_modalias(buf, PAGE_SIZE, id, 1);
len += snprintf(buf + len, PAGE_SIZE-len, "\n");
return len; return max_t(int, len, PAGE_SIZE);
} }
static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL); static CLASS_DEVICE_ATTR(modalias, S_IRUGO, input_dev_show_modalias, NULL);
...@@ -599,7 +609,7 @@ static struct attribute_group input_dev_attr_group = { ...@@ -599,7 +609,7 @@ static struct attribute_group input_dev_attr_group = {
static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \ static ssize_t input_dev_show_id_##name(struct class_device *dev, char *buf) \
{ \ { \
struct input_dev *input_dev = to_input_dev(dev); \ struct input_dev *input_dev = to_input_dev(dev); \
return sprintf(buf, "%04x\n", input_dev->id.name); \ return scnprintf(buf, PAGE_SIZE, "%04x\n", input_dev->id.name); \
} \ } \
static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL); static CLASS_DEVICE_ATTR(name, S_IRUGO, input_dev_show_id_##name, NULL);
...@@ -625,7 +635,9 @@ static struct attribute_group input_dev_id_attr_group = { ...@@ -625,7 +635,9 @@ static struct attribute_group input_dev_id_attr_group = {
static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \ static ssize_t input_dev_show_cap_##bm(struct class_device *dev, char *buf) \
{ \ { \
struct input_dev *input_dev = to_input_dev(dev); \ struct input_dev *input_dev = to_input_dev(dev); \
return input_print_bitmap(buf, PAGE_SIZE, input_dev->bm##bit, ev##_MAX);\ int len = input_print_bitmap(buf, PAGE_SIZE, \
input_dev->bm##bit, ev##_MAX, 1); \
return min_t(int, len, PAGE_SIZE); \
} \ } \
static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL); static CLASS_DEVICE_ATTR(bm, S_IRUGO, input_dev_show_cap_##bm, NULL);
...@@ -684,7 +696,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index, ...@@ -684,7 +696,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
*cur_len += input_print_bitmap(buffer + *cur_len, *cur_len += input_print_bitmap(buffer + *cur_len,
max(buffer_size - *cur_len, 0), max(buffer_size - *cur_len, 0),
bitmap, max) + 1; bitmap, max, 0) + 1;
if (*cur_len > buffer_size) if (*cur_len > buffer_size)
return -ENOMEM; return -ENOMEM;
...@@ -747,7 +759,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp, ...@@ -747,7 +759,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
envp[i++] = buffer + len; envp[i++] = buffer + len;
len += snprintf(buffer + len, buffer_size - len, "MODALIAS="); len += snprintf(buffer + len, buffer_size - len, "MODALIAS=");
len += print_modalias(buffer + len, buffer_size - len, dev) + 1; len += input_print_modalias(buffer + len, buffer_size - len, dev, 0) + 1;
envp[i] = NULL; envp[i] = NULL;
return 0; return 0;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment