diff options
author | Pawel Osciak <p.osciak@samsung.com> | 2010-08-11 05:02:35 +0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2010-08-11 19:59:10 +0400 |
commit | cd7d7e0244955a4694d1e79e8c8a9bef163d6305 (patch) | |
tree | 2f10b24821d854597dce5d2a351cecb547f68894 /drivers/video/s3c-fb.c | |
parent | bc2da1b6fb1a8af9a3226a4f5db3ce32a0a192c9 (diff) | |
download | linux-cd7d7e0244955a4694d1e79e8c8a9bef163d6305.tar.xz |
s3c-fb: fix various null references on framebuffer memory alloc failure
The following problems were found in the above situation:
sfb->windows[win] was being assigned at the end of s3c_fb_probe_win only.
This resulted in passing a NULL to s3c_fb_release_win if probe_win
returned early and a memory leak.
dma_free_writecombine does not allow its third argument to be NULL.
fb_dealloc_cmap does not verify whether its argument is not NULL.
Signed-off-by: Pawel Osciak <p.osciak@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Cc: InKi Dae <inki.dae@samsung.com>
Cc: Ben Dooks <ben-linux@fluff.org>
Cc: Marek Szyprowski <m.szyprowski@samsung.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Diffstat (limited to 'drivers/video/s3c-fb.c')
-rw-r--r-- | drivers/video/s3c-fb.c | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/drivers/video/s3c-fb.c b/drivers/video/s3c-fb.c index b00c064beddf..77f576589a89 100644 --- a/drivers/video/s3c-fb.c +++ b/drivers/video/s3c-fb.c @@ -804,7 +804,8 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win) { struct fb_info *fbi = win->fbinfo; - dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), + if (fbi->screen_base) + dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len), fbi->screen_base, fbi->fix.smem_start); } @@ -819,7 +820,8 @@ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win) { if (win->fbinfo) { unregister_framebuffer(win->fbinfo); - fb_dealloc_cmap(&win->fbinfo->cmap); + if (win->fbinfo->cmap.len) + fb_dealloc_cmap(&win->fbinfo->cmap); s3c_fb_free_memory(sfb, win); framebuffer_release(win->fbinfo); } @@ -865,6 +867,7 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, WARN_ON(windata->win_mode.yres == 0); win = fbinfo->par; + *res = win; var = &fbinfo->var; win->variant = *variant; win->fbinfo = fbinfo; @@ -939,7 +942,6 @@ static int __devinit s3c_fb_probe_win(struct s3c_fb *sfb, unsigned int win_no, return ret; } - *res = win; dev_info(sfb->dev, "window %d: fb %s\n", win_no, fbinfo->fix.id); return 0; |