]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
fbdev: Fix fb_new_modelist to prevent null-ptr-deref in fb_videomode_to_var
authorIan Bridges <icb@fastmail.org>
Thu, 25 Jun 2026 04:13:12 +0000 (23:13 -0500)
committerHelge Deller <deller@gmx.de>
Fri, 26 Jun 2026 13:12:45 +0000 (15:12 +0200)
info->var, a framebuffer's current mode, is expected to have a matching
entry in info->modelist. var_to_display() relies on this and treats a
failed fb_match_mode() as "This should not happen". fb_set_var() keeps it
true by adding the mode to the list on every change, and
do_register_framebuffer() does the same at registration.

store_modes() replaces the modelist from userspace. fb_new_modelist()
validates the new modes but does not check that info->var still has a
match. It relies on fbcon_new_modelist() to re-point consoles, but that
only handles consoles mapped to the framebuffer. With fbcon unbound there
are none, so info->var is left describing a mode that is no longer in the
list.

A later console takeover runs var_to_display(), where fb_match_mode()
returns NULL and leaves fb_display[i].mode NULL. fbcon_switch() passes it
to display_to_var(), and fb_videomode_to_var() dereferences the NULL mode.

Keep the current mode in the list in fb_new_modelist(), the same way
fb_set_var() does.

Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Ian Bridges <icb@fastmail.org>
Signed-off-by: Helge Deller <deller@gmx.de>
drivers/video/fbdev/core/fbmem.c

index e5221653ec2b9a453a4cedc0d1532f290cfb73e0..2f1c56e5a7a232572d1400789b6e1682ecc089ea 100644 (file)
@@ -767,6 +767,18 @@ int fb_new_modelist(struct fb_info *info)
        if (list_empty(&info->modelist))
                return 1;
 
+       /*
+        * The new modelist may not contain the current mode (info->var), and
+        * fbcon_new_modelist() below only re-points consoles mapped to this
+        * framebuffer. Add the current mode here so info->var keeps a match
+        * even when fbcon is unbound.
+        */
+       if (!fb_match_mode(&info->var, &info->modelist)) {
+               fb_var_to_videomode(&mode, &info->var);
+               if (fb_add_videomode(&mode, &info->modelist))
+                       return 1;
+       }
+
        fbcon_new_modelist(info);
 
        return 0;