lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [thread-next>] [day] [month] [year] [list]
Date:   Mon, 20 Jan 2020 11:00:13 +0100
From:   Gerd Hoffmann <kraxel@...hat.com>
To:     dri-devel@...ts.freedesktop.org
Cc:     marmarek@...isiblethingslab.com, Gerd Hoffmann <kraxel@...hat.com>,
        Bartlomiej Zolnierkiewicz <b.zolnierkie@...sung.com>,
        linux-fbdev@...r.kernel.org (open list:FRAMEBUFFER LAYER),
        linux-kernel@...r.kernel.org (open list)
Subject: [PATCH] fbdev: wait for references go away

Problem: do_unregister_framebuffer() might return before the device is
fully cleaned up, due to userspace having a file handle for /dev/fb0
open.  Which can result in drm driver not being able to grab resources
(and fail initialization) because the firmware framebuffer still holds
them.  Reportedly plymouth can trigger this.

Fix this by trying to wait until all references are gone.  Don't wait
forever though given that userspace might keep the file handle open.

Reported-by: Marek Marczykowski-Górecki <marmarek@...isiblethingslab.com>
Signed-off-by: Gerd Hoffmann <kraxel@...hat.com>
---
 drivers/video/fbdev/core/fbmem.c | 7 +++++++
 1 file changed, 7 insertions(+)

diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index d04554959ea7..2ea8ac05b065 100644
--- a/drivers/video/fbdev/core/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
@@ -35,6 +35,7 @@
 #include <linux/fbcon.h>
 #include <linux/mem_encrypt.h>
 #include <linux/pci.h>
+#include <linux/delay.h>
 
 #include <asm/fb.h>
 
@@ -1707,6 +1708,8 @@ static void unlink_framebuffer(struct fb_info *fb_info)
 
 static void do_unregister_framebuffer(struct fb_info *fb_info)
 {
+	int limit = 100;
+
 	unlink_framebuffer(fb_info);
 	if (fb_info->pixmap.addr &&
 	    (fb_info->pixmap.flags & FB_PIXMAP_DEFAULT))
@@ -1726,6 +1729,10 @@ static void do_unregister_framebuffer(struct fb_info *fb_info)
 	fbcon_fb_unregistered(fb_info);
 	console_unlock();
 
+	/* try wait until all references are gone */
+	while (atomic_read(&fb_info->count) > 1 && --limit > 0)
+		msleep(10);
+
 	/* this may free fb info */
 	put_fb_info(fb_info);
 }
-- 
2.18.1

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ