From: Sakari Ailus <sakari.ai...@linux.intel.com>

This helps not acquiring the mutex during copying of the IOCTL argument
from or to user space.

Signed-off-by: Sakari Ailus <sakari.ai...@linux.intel.com>
Signed-off-by: Laurent Pinchart <laurent.pinchart+rene...@ideasonboard.com>
---
 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

Reply via email to