On Wed, Feb 20, 2013 at 05:53:59PM +0530, Shankar Brahadeeswaran wrote:
>  static int set_name(struct ashmem_area *asma, void __user *name)
>  {
>       int ret = 0;
> -
> -     mutex_lock(&ashmem_mutex);
> +     char local_name[ASHMEM_NAME_LEN];
>  
>       /* cannot change an existing mapping's name */
>       if (unlikely(asma->file)) {
> @@ -423,9 +422,22 @@ static int set_name(struct ashmem_area *asma, void 
> __user *name)
>               goto out;

You're not holding the lock here so you can return directly.
Otherwise it's a double unlock.

>       }
>  
> -     if (unlikely(copy_from_user(asma->name + ASHMEM_NAME_PREFIX_LEN,
> -                                 name, ASHMEM_NAME_LEN)))
> +     /*
> +      * Holding the ashmem_mutex while doing a copy_from_user might cause
> +      * an data abourt which would try to access mmap_sem. If another
> +      * thread has invoked ashmem_mmap then it will be holding the
> +      * semaphore and will be waiting for ashmem_mutex, there by leading to
> +      * deadlock. We'll release the mutex  and take the name to a local
> +      * variable that does not need protection and later copy the local
> +      * variable to the structure member with lock held.
> +      */
> +     if (unlikely(copy_from_user(local_name, name, ASHMEM_NAME_LEN))) {
>               ret = -EFAULT;
> +             return ret;

                return -EFAULT;

These weren't there in the original, only when you redid it at my
request.  :/  Sorry for that.

regards,
dan carpenter

_______________________________________________
devel mailing list
[email protected]
http://driverdev.linuxdriverproject.org/mailman/listinfo/devel

Reply via email to