The ioremap() and ioremap_wt() calls in platinumfb_probe() were not
checked for failure. If any of these mappings fail, the driver would
dereference NULL pointers, leading to a kernel panic.

Add proper error checking and use goto-based cleanup to avoid code
duplication across the error paths.

Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: yuebingkun <[email protected]>
---
 drivers/video/fbdev/platinumfb.c | 36 ++++++++++++++++++++++++++------
 1 file changed, 30 insertions(+), 6 deletions(-)

diff --git a/drivers/video/fbdev/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index fa27a3a4f05b..fdffadcc3e73 100644
--- a/drivers/video/fbdev/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
@@ -567,15 +567,30 @@ static int platinumfb_probe(struct platform_device* odev)
        /* frame buffer - map only 4MB */
        pinfo->frame_buffer_phys = pinfo->rsrc_fb.start;
        pinfo->frame_buffer = ioremap_wt(pinfo->rsrc_fb.start, 0x400000);
+       if (!pinfo->frame_buffer) {
+               dev_err(&odev->dev, "failed to ioremap frame buffer\n");
+               rc = -ENOMEM;
+               goto err_release_fb;
+       }
        pinfo->base_frame_buffer = pinfo->frame_buffer;
 
        /* registers */
        pinfo->platinum_regs_phys = pinfo->rsrc_reg.start;
        pinfo->platinum_regs = ioremap(pinfo->rsrc_reg.start, 0x1000);
+       if (!pinfo->platinum_regs) {
+               dev_err(&odev->dev, "failed to ioremap registers\n");
+               rc = -ENOMEM;
+               goto err_unmap_fb;
+       }
 
        pinfo->cmap_regs_phys = 0xf301b000;     /* XXX not in prom? */
        request_mem_region(pinfo->cmap_regs_phys, 0x1000, "platinumfb cmap");
        pinfo->cmap_regs = ioremap(pinfo->cmap_regs_phys, 0x1000);
+       if (!pinfo->cmap_regs) {
+               dev_err(&odev->dev, "failed to ioremap cmap registers\n");
+               rc = -ENOMEM;
+               goto err_release_cmap;
+       }
 
        /* Grok total video ram */
        out_be32(&pinfo->platinum_regs->reg[16].r, 
(unsigned)pinfo->frame_buffer_phys);
@@ -623,13 +638,22 @@ static int platinumfb_probe(struct platform_device* odev)
        dev_set_drvdata(&odev->dev, info);
 
        rc = platinum_init_fb(info);
-       if (rc != 0) {
-               iounmap(pinfo->frame_buffer);
-               iounmap(pinfo->platinum_regs);
-               iounmap(pinfo->cmap_regs);
-               framebuffer_release(info);
-       }
+       if (rc != 0)
+               goto err_unmap_cmap;
+
+       return 0;
 
+err_unmap_cmap:
+       iounmap(pinfo->cmap_regs);
+err_release_cmap:
+       release_mem_region(pinfo->cmap_regs_phys, 0x1000);
+err_unmap_regs:
+       iounmap(pinfo->platinum_regs);
+err_unmap_fb:
+       iounmap(pinfo->frame_buffer);
+err_release_fb:
+       release_mem_region(pinfo->rsrc_fb.start, 
resource_size(&pinfo->rsrc_fb));
+       framebuffer_release(info);
        return rc;
 }
 
-- 
2.43.0

Reply via email to