MLK-11911-2 mxc IPUv3: device: Correct bailout path for the ioctrl IPU_ALLOC
authorLiu Ying <Ying.Liu@freescale.com>
Thu, 26 Nov 2015 07:51:44 +0000 (15:51 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:49:16 +0000 (14:49 -0500)
We should do the bailout dance correctly for the ioctrl IPU_ALLOC:
- Free the mem pointer.
- Free the DMA.
- Delete the mem->list from the ipu_alloc_list.

The potential memory leakage issue on the mem pointer is reported by Coverity:
if (get_user(size, argp))
Resource leak (RESOURCE_LEAK)
leaked_storage: Variable mem going out of scope leaks the storage it points to.
return -EFAULT;

Signed-off-by: Liu Ying <Ying.Liu@freescale.com>
drivers/mxc/ipu3/ipu_device.c

index f672b0e..c6cfc97 100644 (file)
@@ -3514,8 +3514,10 @@ static long mxc_ipu_ioctl(struct file *file,
                        if (mem == NULL)
                                return -ENOMEM;
 
-                       if (get_user(size, argp))
+                       if (get_user(size, argp)) {
+                               kfree(mem);
                                return -EFAULT;
+                       }
 
                        mem->size = PAGE_ALIGN(size);
 
@@ -3531,12 +3533,21 @@ static long mxc_ipu_ioctl(struct file *file,
                        list_add(&mem->list, &ipu_alloc_list);
                        mutex_unlock(&ipu_alloc_lock);
 
+                       if (put_user(mem->phy_addr, argp)) {
+                               mutex_lock(&ipu_alloc_lock);
+                               list_del(&mem->list);
+                               mutex_unlock(&ipu_alloc_lock);
+                               dma_free_coherent(ipu_dev,
+                                                 mem->size,
+                                                 mem->cpu_addr,
+                                                 mem->phy_addr);
+                               kfree(mem);
+                               return -EFAULT;
+                       }
+
                        dev_dbg(ipu_dev, "allocated %d bytes @ 0x%08X\n",
                                mem->size, mem->phy_addr);
 
-                       if (put_user(mem->phy_addr, argp))
-                               return -EFAULT;
-
                        break;
                }
        case IPU_FREE: