MLK-11918-3 video: mxc ipuv3 fb: Fix bailout path for ioctrl FBIO_ALLOC
authorLiu Ying <Ying.Liu@freescale.com>
Mon, 30 Nov 2015 03:01:07 +0000 (11:01 +0800)
committerNitin Garg <nitin.garg@nxp.com>
Mon, 19 Mar 2018 19:49:19 +0000 (14:49 -0500)
Resources(kmem and DMA) should be freed correctly in the bailout path of
ioctrl FBIO_ALLOC.  We should also delete mem->list from fb_alloc_list
in the bailout path if necessary.

The kmem leakage issue 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/video/fbdev/mxc/mxc_ipuv3_fb.c

index d3f4825..6fe8d0f 100644 (file)
@@ -2123,8 +2123,10 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
                        if (mem == NULL)
                                return -ENOMEM;
 
-                       if (get_user(size, argp))
+                       if (get_user(size, argp)) {
+                               kfree(mem);
                                return -EFAULT;
+                       }
 
                        mem->size = PAGE_ALIGN(size);
 
@@ -2138,12 +2140,19 @@ static int mxcfb_ioctl(struct fb_info *fbi, unsigned int cmd, unsigned long arg)
 
                        list_add(&mem->list, &fb_alloc_list);
 
+                       if (put_user(mem->phy_addr, argp)) {
+                               list_del(&mem->list);
+                               dma_free_coherent(fbi->device,
+                                                 mem->size,
+                                                 mem->cpu_addr,
+                                                 mem->phy_addr);
+                               kfree(mem);
+                               return -EFAULT;
+                       }
+
                        dev_dbg(fbi->device, "allocated %d bytes @ 0x%08X\n",
                                mem->size, mem->phy_addr);
 
-                       if (put_user(mem->phy_addr, argp))
-                               return -EFAULT;
-
                        break;
                }
        case FBIO_FREE: