From: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> This helps not acquiring the mutex during copying of the IOCTL argument from or to user space. Signed-off-by: Sakari Ailus <sakari.ailus@xxxxxxxxxxxxxxx> Signed-off-by: Laurent Pinchart <laurent.pinchart+renesas@xxxxxxxxxxxxxxxx> --- drivers/media/media-device.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/drivers/media/media-device.c b/drivers/media/media-device.c index c8d104d935da..3850775cc127 100644 --- a/drivers/media/media-device.c +++ b/drivers/media/media-device.c @@ -465,33 +465,38 @@ static long media_device_setup_link(struct media_device *mdev, struct media_link_desc ulink; struct media_entity *source; struct media_entity *sink; - int ret; + int ret = -EINVAL; if (copy_from_user(&ulink, _ulink, sizeof(ulink))) return -EFAULT; + mutex_lock(&dev->graph_mutex); + /* Find the source and sink entities and link. */ source = find_entity(mdev, ulink.source.entity); sink = find_entity(mdev, ulink.sink.entity); if (source == NULL || sink == NULL) - return -EINVAL; + goto out; if (ulink.source.index >= source->num_pads || ulink.sink.index >= sink->num_pads) - return -EINVAL; + goto out; link = media_entity_find_link(&source->pads[ulink.source.index], &sink->pads[ulink.sink.index]); if (link == NULL) - return -EINVAL; + goto out; /* Setup the link on both entities. */ ret = __media_entity_setup_link(link, ulink.flags); - if (copy_to_user(_ulink, &ulink, sizeof(ulink))) - return -EFAULT; +out: + mutex_unlock(&dev->graph_mutex); + + if (!ret && copy_to_user(_ulink, &ulink, sizeof(ulink))) + ret = -EFAULT; return ret; } @@ -523,10 +528,8 @@ static long media_device_ioctl(struct file *filp, unsigned int cmd, break; case MEDIA_IOC_SETUP_LINK: - mutex_lock(&dev->graph_mutex); ret = media_device_setup_link(dev, (struct media_link_desc __user *)arg); - mutex_unlock(&dev->graph_mutex); break; case MEDIA_IOC_REQUEST_CMD: -- 2.4.10