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

Commit ac648a6a authored by Dmitry Torokhov's avatar Dmitry Torokhov
Browse files

Input: make modalias code respect allowed buffer size



Signed-off-by: default avatarDmitry Torokhov <dtor@mail.ru>
parent 969b21cd
Loading
Loading
Loading
Loading
+71 −39
Original line number Original line Diff line number Diff line
@@ -571,15 +571,16 @@ INPUT_DEV_STRING_ATTR_SHOW(name);
INPUT_DEV_STRING_ATTR_SHOW(phys);
INPUT_DEV_STRING_ATTR_SHOW(phys);
INPUT_DEV_STRING_ATTR_SHOW(uniq);
INPUT_DEV_STRING_ATTR_SHOW(uniq);


static int print_modalias_bits(char *buf, int size, char prefix, unsigned long *arr,
static int input_print_modalias_bits(char *buf, int size,
			       unsigned int min, unsigned int max)
				     char name, unsigned long *bm,
				     unsigned int min_bit, unsigned int max_bit)
{
{
	int len, i;
	int len = 0, i;


	len = snprintf(buf, size, "%c", prefix);
	len += snprintf(buf, max(size, 0), "%c", name);
	for (i = min; i < max; i++)
	for (i = min_bit; i < max_bit; i++)
		if (arr[LONG(i)] & BIT(i))
		if (bm[LONG(i)] & BIT(i))
			len += snprintf(buf + len, size - len, "%X,", i);
			len += snprintf(buf + len, max(size - len, 0), "%X,", i);
	return len;
	return len;
}
}


@@ -588,33 +589,32 @@ static int input_print_modalias(char *buf, int size, struct input_dev *id,
{
{
	int len;
	int len;


	len = snprintf(buf, size, "input:b%04Xv%04Xp%04Xe%04X-",
	len = snprintf(buf, max(size, 0),
		       id->id.bustype,
		       "input:b%04Xv%04Xp%04Xe%04X-",
		       id->id.vendor,
		       id->id.bustype, id->id.vendor,
		       id->id.product,
		       id->id.product, id->id.version);
		       id->id.version);


	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'e', id->evbit,
				'e', id->evbit, 0, EV_MAX);
				   0, EV_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'k', id->keybit,
				'k', id->keybit, KEY_MIN_INTERESTING, KEY_MAX);
				   KEY_MIN_INTERESTING, KEY_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'r', id->relbit,
				'r', id->relbit, 0, REL_MAX);
				   0, REL_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'a', id->absbit,
				'a', id->absbit, 0, ABS_MAX);
				   0, ABS_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'm', id->mscbit,
				'm', id->mscbit, 0, MSC_MAX);
				   0, MSC_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'l', id->ledbit,
				'l', id->ledbit, 0, LED_MAX);
				   0, LED_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 's', id->sndbit,
				's', id->sndbit, 0, SND_MAX);
				   0, SND_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'f', id->ffbit,
				'f', id->ffbit, 0, FF_MAX);
				   0, FF_MAX);
	len += input_print_modalias_bits(buf + len, size - len,
	len += print_modalias_bits(buf + len, size - len, 'w', id->swbit,
				'w', id->swbit, 0, SW_MAX);
				   0, SW_MAX);


	if (add_cr)
	if (add_cr)
		len += snprintf(buf + len, size - len, "\n");
		len += snprintf(buf + len, max(size - len, 0), "\n");


	return len;
	return len;
}
}
@@ -748,7 +748,7 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
	envp[*cur_index] = buffer + *cur_len;
	envp[*cur_index] = buffer + *cur_len;


	*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
	*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0), name);
	if (*cur_len > buffer_size)
	if (*cur_len >= buffer_size)
		return -ENOMEM;
		return -ENOMEM;


	*cur_len += input_print_bitmap(buffer + *cur_len,
	*cur_len += input_print_bitmap(buffer + *cur_len,
@@ -761,6 +761,30 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
	return 0;
	return 0;
}
}


static int input_add_uevent_modalias_var(char **envp, int num_envp, int *cur_index,
					 char *buffer, int buffer_size, int *cur_len,
					 struct input_dev *dev)
{
	if (*cur_index >= num_envp - 1)
		return -ENOMEM;

	envp[*cur_index] = buffer + *cur_len;

	*cur_len += snprintf(buffer + *cur_len, max(buffer_size - *cur_len, 0),
			     "MODALIAS=");
	if (*cur_len >= buffer_size)
		return -ENOMEM;

	*cur_len += input_print_modalias(buffer + *cur_len,
					 max(buffer_size - *cur_len, 0),
					 dev, 0) + 1;
	if (*cur_len > buffer_size)
		return -ENOMEM;

	(*cur_index)++;
	return 0;
}

#define INPUT_ADD_HOTPLUG_VAR(fmt, val...)				\
#define INPUT_ADD_HOTPLUG_VAR(fmt, val...)				\
	do {								\
	do {								\
		int err = add_uevent_var(envp, num_envp, &i,		\
		int err = add_uevent_var(envp, num_envp, &i,		\
@@ -779,6 +803,16 @@ static int input_add_uevent_bm_var(char **envp, int num_envp, int *cur_index,
			return err;					\
			return err;					\
	} while (0)
	} while (0)


#define INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev)				\
	do {								\
		int err = input_add_uevent_modalias_var(envp,		\
					num_envp, &i,			\
					buffer, buffer_size, &len,	\
					dev);				\
		if (err)						\
			return err;					\
	} while (0)

static int input_dev_uevent(struct class_device *cdev, char **envp,
static int input_dev_uevent(struct class_device *cdev, char **envp,
			    int num_envp, char *buffer, int buffer_size)
			    int num_envp, char *buffer, int buffer_size)
{
{
@@ -814,9 +848,7 @@ static int input_dev_uevent(struct class_device *cdev, char **envp,
	if (test_bit(EV_SW, dev->evbit))
	if (test_bit(EV_SW, dev->evbit))
		INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);
		INPUT_ADD_HOTPLUG_BM_VAR("SW=", dev->swbit, SW_MAX);


	envp[i++] = buffer + len;
	INPUT_ADD_HOTPLUG_MODALIAS_VAR(dev);
	len += snprintf(buffer + len, buffer_size - len, "MODALIAS=");
	len += input_print_modalias(buffer + len, buffer_size - len, dev, 0) + 1;


	envp[i] = NULL;
	envp[i] = NULL;
	return 0;
	return 0;