Commit cd7d7e02 authored by Pawel Osciak's avatar Pawel Osciak Committed by Linus Torvalds
Browse files

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: default avatarPawel Osciak <p.osciak@samsung.com>
Signed-off-by: default avatarKyungmin 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: default avatarAndrew Morton <akpm@linux-foundation.org>
Signed-off-by: default avatarLinus Torvalds <torvalds@linux-foundation.org>
parent bc2da1b6
Loading
Loading
Loading
Loading
+5 −3
Original line number Diff line number Diff line
@@ -804,6 +804,7 @@ static void s3c_fb_free_memory(struct s3c_fb *sfb, struct s3c_fb_win *win)
{
	struct fb_info *fbi = win->fbinfo;

	if (fbi->screen_base)
		dma_free_writecombine(sfb->dev, PAGE_ALIGN(fbi->fix.smem_len),
			      fbi->screen_base, fbi->fix.smem_start);
}
@@ -819,6 +820,7 @@ static void s3c_fb_release_win(struct s3c_fb *sfb, struct s3c_fb_win *win)
{
	if (win->fbinfo) {
		unregister_framebuffer(win->fbinfo);
		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;