mirror of
https://github.com/armbian/linux.git
synced 2026-01-06 10:13:00 -08:00
staging:iio:events: Don't copy data to user-space with a locked spinlock.
iio_event_chrdev_read would return -EFAULT if the user-space page was not resident. Change-Id: I4ac5d3bc791bb503d014d9db576b9d6d522505b2 Signed-off-by: Arve Hjønnevåg <arve@android.com>
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
*/
|
||||
struct iio_event_interface {
|
||||
wait_queue_head_t wait;
|
||||
struct mutex read_lock;
|
||||
DECLARE_KFIFO(det_events, struct iio_event_data, 16);
|
||||
|
||||
struct list_head dev_attr_list;
|
||||
@@ -97,14 +98,16 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
|
||||
if (count < sizeof(struct iio_event_data))
|
||||
return -EINVAL;
|
||||
|
||||
spin_lock_irq(&ev_int->wait.lock);
|
||||
if (mutex_lock_interruptible(&ev_int->read_lock))
|
||||
return -ERESTARTSYS;
|
||||
|
||||
if (kfifo_is_empty(&ev_int->det_events)) {
|
||||
if (filep->f_flags & O_NONBLOCK) {
|
||||
ret = -EAGAIN;
|
||||
goto error_unlock;
|
||||
}
|
||||
/* Blocking on device; waiting for something to be there */
|
||||
ret = wait_event_interruptible_locked_irq(ev_int->wait,
|
||||
ret = wait_event_interruptible(ev_int->wait,
|
||||
!kfifo_is_empty(&ev_int->det_events));
|
||||
if (ret)
|
||||
goto error_unlock;
|
||||
@@ -114,7 +117,7 @@ static ssize_t iio_event_chrdev_read(struct file *filep,
|
||||
ret = kfifo_to_user(&ev_int->det_events, buf, count, &copied);
|
||||
|
||||
error_unlock:
|
||||
spin_unlock_irq(&ev_int->wait.lock);
|
||||
mutex_unlock(&ev_int->read_lock);
|
||||
|
||||
return ret ? ret : copied;
|
||||
}
|
||||
@@ -371,6 +374,7 @@ static void iio_setup_ev_int(struct iio_event_interface *ev_int)
|
||||
{
|
||||
INIT_KFIFO(ev_int->det_events);
|
||||
init_waitqueue_head(&ev_int->wait);
|
||||
mutex_init(&ev_int->read_lock);
|
||||
}
|
||||
|
||||
static const char *iio_event_group_name = "events";
|
||||
@@ -434,6 +438,7 @@ int iio_device_register_eventset(struct iio_dev *indio_dev)
|
||||
|
||||
error_free_setup_event_lines:
|
||||
__iio_remove_event_config_attrs(indio_dev);
|
||||
mutex_destroy(&indio_dev->event_interface->read_lock);
|
||||
kfree(indio_dev->event_interface);
|
||||
error_ret:
|
||||
|
||||
@@ -446,5 +451,6 @@ void iio_device_unregister_eventset(struct iio_dev *indio_dev)
|
||||
return;
|
||||
__iio_remove_event_config_attrs(indio_dev);
|
||||
kfree(indio_dev->event_interface->group.attrs);
|
||||
mutex_destroy(&indio_dev->event_interface->read_lock);
|
||||
kfree(indio_dev->event_interface);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user