From c590cece75728a85ea06801df3ebad2d7ad8612c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Bruno=20Pr=C3=A9mont?= <bonbons@linux-vserver.org>
Date: Sat, 14 May 2011 12:24:15 +0200
Subject: [PATCH] Further fbcon sanity checking
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

This moves the

    if (num_registered_fb == FB_MAX)
            return -ENXIO;

check _AFTER_ the call to do_remove_conflicting_framebuffers() as this
would (now in a safe way) allow a native driver to replace the
conflicting one even if all slots in registered_fb[] are taken.

This also prevents unregistering a framebuffer that is no longer
registered (vga16f will unregister at module unload time even if the
frame buffer had been unregistered earlier due to being found
conflicting).

Signed-off-by: Bruno Prémont <bonbons@linux-vserver.org>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
---
 drivers/video/fbmem.c | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 46ee5e5a08c6..5aac00eb1830 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1573,15 +1573,15 @@ static int do_register_framebuffer(struct fb_info *fb_info)
 	struct fb_event event;
 	struct fb_videomode mode;
 
-	if (num_registered_fb == FB_MAX)
-		return -ENXIO;
-
 	if (fb_check_foreignness(fb_info))
 		return -ENOSYS;
 
 	do_remove_conflicting_framebuffers(fb_info->apertures, fb_info->fix.id,
 					 fb_is_primary_device(fb_info));
 
+	if (num_registered_fb == FB_MAX)
+		return -ENXIO;
+
 	num_registered_fb++;
 	for (i = 0 ; i < FB_MAX; i++)
 		if (!registered_fb[i])
@@ -1639,7 +1639,7 @@ static int do_unregister_framebuffer(struct fb_info *fb_info)
 	int i, ret = 0;
 
 	i = fb_info->node;
-	if (!registered_fb[i])
+	if (i < 0 || i >= FB_MAX || registered_fb[i] != fb_info)
 		return -EINVAL;
 
 	if (!lock_fb_info(fb_info))
-- 
GitLab