Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

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

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
Loading
Loading
Loading
Loading
+24 −12
Original line number Original line Diff line number Diff line
@@ -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
	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)
	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) \
	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 *
	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)
				   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)
	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 = {
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 = {
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,


	*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,


	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;