1446 lines · 32.4 KB · C
RawDownload
	/*	 * Limit amount of data we inject into the input subsystem so that	 * we do not hold evdev->mutex for too long. 4096 bytes corresponds	 * to 170 input events.	 */	count = min(count, 4096); 	if (count != 0 && count < input_event_size())		return -EINVAL; 	retval = mutex_lock_interruptible(&evdev->mutex);	if (retval)		return retval; 	if (!evdev->exist || client->revoked) {		retval = -ENODEV;		goto out;	} 	while (retval + input_event_size() <= count) { 		if (input_event_from_user(buffer + retval, &event)) {			retval = -EFAULT;			goto out;		}		retval += input_event_size(); 		input_inject_event(&evdev->handle,				   event.type, event.code, event.value);		cond_resched();	}  out:	mutex_unlock(&evdev->mutex);	return retval;} static int evdev_fetch_next_event(struct evdev_client *client,				  struct input_event *event){	int have_event; 	spin_lock_irq(&client->buffer_lock); 	have_event = client->packet_head != client->tail;	if (have_event) {		*event = client->buffer[client->tail++];		client->tail &= client->bufsize - 1;	} 	spin_unlock_irq(&client->buffer_lock); 	return have_event;} static ssize_t evdev_read(struct file *file, char __user *buffer,			  size_t count, loff_t *ppos){	struct evdev_client *client = file->private_data;	struct evdev *evdev = client->evdev;	struct input_event event;	size_t read = 0;	int error; 	if (count != 0 && count < input_event_size())		return -EINVAL; 	for (;;) {		if (!evdev->exist || client->revoked)			return -ENODEV; 		if (client->packet_head == client->tail &&		    (file->f_flags & O_NONBLOCK))			return -EAGAIN; 		/*		 * count == 0 is special - no IO is done but we check		 * for error conditions (see above).		 */		if (count == 0)			break; 		while (read + input_event_size() <= count &&		       evdev_fetch_next_event(client, &event)) { 			if (input_event_to_user(buffer + read, &event))				return -EFAULT; 			read += input_event_size();		} 		if (read)			break; 		if (!(file->f_flags & O_NONBLOCK)) {			error = wait_event_interruptible(client->wait,					client->packet_head != client->tail ||					!evdev->exist || client->revoked);			if (error)				return error;		}	} 	return read;} /* No kernel lock - fine */static __poll_t evdev_poll(struct file *file, poll_table *wait){	struct evdev_client *client = file->private_data;	struct evdev *evdev = client->evdev;	__poll_t mask; 	poll_wait(file, &client->wait, wait); 	if (evdev->exist && !client->revoked)		mask = EPOLLOUT | EPOLLWRNORM;	else		mask = EPOLLHUP | EPOLLERR; 	if (client->packet_head != client->tail)		mask |= EPOLLIN | EPOLLRDNORM; 	return mask;} #ifdef CONFIG_COMPAT #define BITS_PER_LONG_COMPAT (sizeof(compat_long_t) * 8)#define BITS_TO_LONGS_COMPAT(x) ((((x) - 1) / BITS_PER_LONG_COMPAT) + 1) #ifdef __BIG_ENDIANstatic int bits_to_user(unsigned long *bits, unsigned int maxbit,			unsigned int maxlen, void __user *p, int compat){	int len, i; 	if (compat) {		len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);		if (len > maxlen)			len = maxlen; 		for (i = 0; i < len / sizeof(compat_long_t); i++)			if (copy_to_user((compat_long_t __user *) p + i,					 (compat_long_t *) bits +						i + 1 - ((i % 2) << 1),					 sizeof(compat_long_t)))				return -EFAULT;	} else {		len = BITS_TO_LONGS(maxbit) * sizeof(long);		if (len > maxlen)			len = maxlen; 		if (copy_to_user(p, bits, len))			return -EFAULT;	} 	return len;} static int bits_from_user(unsigned long *bits, unsigned int maxbit,			  unsigned int maxlen, const void __user *p, int compat){	int len, i; 	if (compat) {		if (maxlen % sizeof(compat_long_t))			return -EINVAL; 		len = BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t);		if (len > maxlen)			len = maxlen; 		for (i = 0; i < len / sizeof(compat_long_t); i++)			if (copy_from_user((compat_long_t *) bits +						i + 1 - ((i % 2) << 1),					   (compat_long_t __user *) p + i,					   sizeof(compat_long_t)))				return -EFAULT;		if (i % 2)			*((compat_long_t *) bits + i - 1) = 0; 	} else {		if (maxlen % sizeof(long))			return -EINVAL; 		len = BITS_TO_LONGS(maxbit) * sizeof(long);		if (len > maxlen)			len = maxlen; 		if (copy_from_user(bits, p, len))			return -EFAULT;	} 	return len;} #else static int bits_to_user(unsigned long *bits, unsigned int maxbit,			unsigned int maxlen, void __user *p, int compat){	int len = compat ?			BITS_TO_LONGS_COMPAT(maxbit) * sizeof(compat_long_t) :			BITS_TO_LONGS(maxbit) * sizeof(long); 	if (len > maxlen)		len = maxlen; 	return copy_to_user(p, bits, len) ? -EFAULT : len;} static int bits_from_user(unsigned long *bits, unsigned int maxbit,			  unsigned int maxlen, const void __user *p, int compat){	size_t chunk_size = compat ? sizeof(compat_long_t) : sizeof(long);	int len; 	if (maxlen % chunk_size)		return -EINVAL; 	len = compat ? BITS_TO_LONGS_COMPAT(maxbit) : BITS_TO_LONGS(maxbit);	len *= chunk_size;	if (len > maxlen)		len = maxlen; 	return copy_from_user(bits, p, len) ? -EFAULT : len;} #endif /* __BIG_ENDIAN */ #else static int bits_to_user(unsigned long *bits, unsigned int maxbit,			unsigned int maxlen, void __user *p, int compat){	int len = BITS_TO_LONGS(maxbit) * sizeof(long); 	if (len > maxlen)		len = maxlen; 	return copy_to_user(p, bits, len) ? -EFAULT : len;} static int bits_from_user(unsigned long *bits, unsigned int maxbit,			  unsigned int maxlen, const void __user *p, int compat){	int len; 	if (maxlen % sizeof(long))		return -EINVAL; 	len = BITS_TO_LONGS(maxbit) * sizeof(long);	if (len > maxlen)		len = maxlen; 	return copy_from_user(bits, p, len) ? -EFAULT : len;} #endif /* CONFIG_COMPAT */ static int str_to_user(const char *str, unsigned int maxlen, void __user *p){	int len; 	if (!str)		return -ENOENT; 	len = strlen(str) + 1;	if (len > maxlen)		len = maxlen; 	return copy_to_user(p, str, len) ? -EFAULT : len;} static int handle_eviocgbit(struct input_dev *dev,			    unsigned int type, unsigned int size,			    void __user *p, int compat_mode){	unsigned long *bits;	int len; 	switch (type) { 	case      0: bits = dev->evbit;  len = EV_MAX;  break;	case EV_KEY: bits = dev->keybit; len = KEY_MAX; break;	case EV_REL: bits = dev->relbit; len = REL_MAX; break;	case EV_ABS: bits = dev->absbit; len = ABS_MAX; break;	case EV_MSC: bits = dev->mscbit; len = MSC_MAX; break;	case EV_LED: bits = dev->ledbit; len = LED_MAX; break;	case EV_SND: bits = dev->sndbit; len = SND_MAX; break;	case EV_FF:  bits = dev->ffbit;  len = FF_MAX;  break;	case EV_SW:  bits = dev->swbit;  len = SW_MAX;  break;	default: return -EINVAL;	} 	return bits_to_user(bits, len, size, p, compat_mode);} static int evdev_handle_get_keycode(struct input_dev *dev, void __user *p){	struct input_keymap_entry ke = {		.len	= sizeof(unsigned int),		.flags	= 0,	};	int __user *ip = (int __user *)p;	int error; 	/* legacy case */	if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))		return -EFAULT; 	error = input_get_keycode(dev, &ke);	if (error)		return error; 	if (put_user(ke.keycode, ip + 1))		return -EFAULT; 	return 0;} static int evdev_handle_get_keycode_v2(struct input_dev *dev, void __user *p){	struct input_keymap_entry ke;	int error; 	if (copy_from_user(&ke, p, sizeof(ke)))		return -EFAULT; 	error = input_get_keycode(dev, &ke);	if (error)		return error; 	if (copy_to_user(p, &ke, sizeof(ke)))		return -EFAULT; 	return 0;} static int evdev_handle_set_keycode(struct input_dev *dev, void __user *p){	struct input_keymap_entry ke = {		.len	= sizeof(unsigned int),		.flags	= 0,	};	int __user *ip = (int __user *)p; 	if (copy_from_user(ke.scancode, p, sizeof(unsigned int)))		return -EFAULT; 	if (get_user(ke.keycode, ip + 1))		return -EFAULT; 	return input_set_keycode(dev, &ke);} static int evdev_handle_set_keycode_v2(struct input_dev *dev, void __user *p){	struct input_keymap_entry ke; 	if (copy_from_user(&ke, p, sizeof(ke)))		return -EFAULT; 	if (ke.len > sizeof(ke.scancode))		return -EINVAL; 	return input_set_keycode(dev, &ke);} /* * If we transfer state to the user, we should flush all pending events * of the same type from the client's queue. Otherwise, they might end up * with duplicate events, which can screw up client's state tracking. * If bits_to_user fails after flushing the queue, we queue a SYN_DROPPED * event so user-space will notice missing events. * * LOCKING: * We need to take event_lock before buffer_lock to avoid dead-locks. But we * need the even_lock only to guarantee consistent state. We can safely release * it while flushing the queue. This allows input-core to handle filters while * we flush the queue. */static int evdev_handle_get_val(struct evdev_client *client,				struct input_dev *dev, unsigned int type,				unsigned long *bits, unsigned int maxbit,				unsigned int maxlen, void __user *p,				int compat){	int ret;	unsigned long *mem; 	mem = bitmap_alloc(maxbit, GFP_KERNEL);	if (!mem)		return -ENOMEM; 	spin_lock_irq(&dev->event_lock);	spin_lock(&client->buffer_lock); 	bitmap_copy(mem, bits, maxbit); 	spin_unlock(&dev->event_lock); 	__evdev_flush_queue(client, type); 	spin_unlock_irq(&client->buffer_lock); 	ret = bits_to_user(mem, maxbit, maxlen, p, compat);	if (ret < 0)		evdev_queue_syn_dropped(client); 	bitmap_free(mem); 	return ret;} static int evdev_handle_mt_request(struct input_dev *dev,				   unsigned int size,				   int __user *ip){	const struct input_mt *mt = dev->mt;	unsigned int code;	int max_slots;	int i; 	if (get_user(code, &ip[0]))		return -EFAULT;	if (!mt || !input_is_mt_value(code))		return -EINVAL; 	max_slots = (size - sizeof(__u32)) / sizeof(__s32);	for (i = 0; i < mt->num_slots && i < max_slots; i++) {		int value = input_mt_get_value(&mt->slots[i], code);		if (put_user(value, &ip[1 + i]))			return -EFAULT;	} 	return 0;} static int evdev_revoke(struct evdev *evdev, struct evdev_client *client,			struct file *file){	client->revoked = true;	evdev_ungrab(evdev, client);	input_flush_device(&evdev->handle, file);	wake_up_interruptible_poll(&client->wait, EPOLLHUP | EPOLLERR); 	return 0;} /* must be called with evdev-mutex held */static int evdev_set_mask(struct evdev_client *client,			  unsigned int type,			  const void __user *codes,			  u32 codes_size,			  int compat){	unsigned long flags, *mask, *oldmask;	size_t cnt;	int error; 	/* we allow unknown types and 'codes_size > size' for forward-compat */	cnt = evdev_get_mask_cnt(type);	if (!cnt)		return 0; 	mask = bitmap_zalloc(cnt, GFP_KERNEL);	if (!mask)		return -ENOMEM; 	error = bits_from_user(mask, cnt - 1, codes_size, codes, compat);	if (error < 0) {		bitmap_free(mask);		return error;	} 	spin_lock_irqsave(&client->buffer_lock, flags);	oldmask = client->evmasks[type];	client->evmasks[type] = mask;	spin_unlock_irqrestore(&client->buffer_lock, flags); 	bitmap_free(oldmask); 	return 0;} /* must be called with evdev-mutex held */static int evdev_get_mask(struct evdev_client *client,			  unsigned int type,			  void __user *codes,			  u32 codes_size,			  int compat){	unsigned long *mask;	size_t cnt, size, xfer_size;	int i;	int error; 	/* we allow unknown types and 'codes_size > size' for forward-compat */

Lines 501–1000 of 1446. Previous lines