From: Markus Elfring <elfring@xxxxxxxxxxxxxxxxxxxxx> Date: Tue, 23 May 2023 15:40:43 +0200 The exception handling was incomplete. The label “error” was used to jump to another pointer check despite of the detail in the implementation of the function “imsttfb_probe” that it was determined already that the corresponding variable contained a null pointer. * Thus use more appropriate labels instead. * Delete two redundant checks. Reported-by: "Michal Koutný" <mkoutny@xxxxxxxx> Link: https://lore.kernel.org/dri-devel/34gbv2k3lc5dl4nbivslizfuor6qc34j63idiiuc35qkk3iohs@7bshmqu2ue7a/ Fixes: c75f5a550610 ("fbdev: imsttfb: Fix use after free bug in imsttfb_probe") Signed-off-by: Markus Elfring <elfring@xxxxxxxxxxxxxxxxxxxxx> --- drivers/video/fbdev/imsttfb.c | 34 +++++++++++++++++++++------------- 1 file changed, 21 insertions(+), 13 deletions(-) diff --git a/drivers/video/fbdev/imsttfb.c b/drivers/video/fbdev/imsttfb.c index d3532def4707..6490f544f8eb 100644 --- a/drivers/video/fbdev/imsttfb.c +++ b/drivers/video/fbdev/imsttfb.c @@ -1503,8 +1503,8 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) if (!request_mem_region(addr, size, "imsttfb")) { printk(KERN_ERR "imsttfb: Can't reserve memory region\n"); - framebuffer_release(info); - return -ENODEV; + ret = -ENODEV; + goto release_framebuffer; } switch (pdev->device) { @@ -1521,34 +1521,42 @@ static int imsttfb_probe(struct pci_dev *pdev, const struct pci_device_id *ent) printk(KERN_INFO "imsttfb: Device 0x%x unknown, " "contact maintainer.\n", pdev->device); ret = -ENODEV; - goto error; + goto release_region; } info->fix.smem_start = addr; info->screen_base = (__u8 *)ioremap(addr, par->ramdac == IBM ? 0x400000 : 0x800000); if (!info->screen_base) - goto error; + goto release_region; + info->fix.mmio_start = addr + 0x800000; par->dc_regs = ioremap(addr + 0x800000, 0x1000); if (!par->dc_regs) - goto error; + goto unmap_io_screen_base; + par->cmap_regs_phys = addr + 0x840000; par->cmap_regs = (__u8 *)ioremap(addr + 0x840000, 0x1000); if (!par->cmap_regs) - goto error; + goto unmap_io_dc_regs; + info->pseudo_palette = par->palette; ret = init_imstt(info); - if (!ret) - pci_set_drvdata(pdev, info); + if (ret) + goto unmap_io_cmap_regs; + + pci_set_drvdata(pdev, info); return ret; -error: - if (par->dc_regs) - iounmap(par->dc_regs); - if (info->screen_base) - iounmap(info->screen_base); +unmap_io_cmap_regs: + iounmap(par->cmap_regs); +unmap_io_dc_regs: + iounmap(par->dc_regs); +unmap_io_screen_base: + iounmap(info->screen_base); +release_region: release_mem_region(addr, size); +release_framebuffer: framebuffer_release(info); return ret; } -- 2.40.1