summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Zimmermann <tzimmermann@suse.de>2026-02-24 11:25:55 +0300
committerHelge Deller <deller@gmx.de>2026-03-09 15:06:48 +0300
commitd460a54fd321997a3a4703816cfb8fb4a520af29 (patch)
tree982ee2aed33e1b289ff83ce615bed1cf63b5f50b
parent9ded47ad003f09a94b6a710b5c47f4aa5ceb7429 (diff)
downloadlinux-d460a54fd321997a3a4703816cfb8fb4a520af29.tar.xz
fbdev: defio: Keep module reference from VMAs
Acquire a module reference on each mmap and VMA open; hold it until the kernel closes the VMA. Protects against unloading the module while user space still has a mapping of the graphics memory. The VMA page-fault handling would then call into undefined code. This situation can happen if the underlying device has been unplugged and the driver has been unloaded. It would then be possible to trigger the bug by unloading the fbdev core module. Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de> Signed-off-by: Helge Deller <deller@gmx.de>
-rw-r--r--drivers/video/fbdev/core/fb_defio.c6
1 files changed, 6 insertions, 0 deletions
diff --git a/drivers/video/fbdev/core/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c
index 93bd2f696fa4..56030eb42f71 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -14,6 +14,7 @@
#include <linux/export.h>
#include <linux/string.h>
#include <linux/mm.h>
+#include <linux/module.h>
#include <linux/vmalloc.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
@@ -83,6 +84,7 @@ static void fb_deferred_io_vm_open(struct vm_area_struct *vma)
{
struct fb_deferred_io_state *fbdefio_state = vma->vm_private_data;
+ WARN_ON_ONCE(!try_module_get(THIS_MODULE));
fb_deferred_io_state_get(fbdefio_state);
}
@@ -91,6 +93,7 @@ static void fb_deferred_io_vm_close(struct vm_area_struct *vma)
struct fb_deferred_io_state *fbdefio_state = vma->vm_private_data;
fb_deferred_io_state_put(fbdefio_state);
+ module_put(THIS_MODULE);
}
static struct page *fb_deferred_io_get_page(struct fb_info *info, unsigned long offs)
@@ -335,6 +338,9 @@ int fb_deferred_io_mmap(struct fb_info *info, struct vm_area_struct *vma)
{
vma->vm_page_prot = pgprot_decrypted(vma->vm_page_prot);
+ if (!try_module_get(THIS_MODULE))
+ return -EINVAL;
+
vma->vm_ops = &fb_deferred_io_vm_ops;
vm_flags_set(vma, VM_DONTEXPAND | VM_DONTDUMP);
if (!(info->flags & FBINFO_VIRTFB))