]> www.infradead.org Git - users/jedix/linux-maple.git/commitdiff
fbdev: Fix vmalloc out-of-bounds write in fast_imageblit
authorSravan Kumar Gundu <sravankumarlpu@gmail.com>
Thu, 31 Jul 2025 20:36:18 +0000 (15:36 -0500)
committerHelge Deller <deller@gmx.de>
Sat, 2 Aug 2025 19:47:32 +0000 (21:47 +0200)
This issue triggers when a userspace program does an ioctl
FBIOPUT_CON2FBMAP by passing console number and frame buffer number.
Ideally this maps console to frame buffer and updates the screen if
console is visible.

As part of mapping it has to do resize of console according to frame
buffer info. if this resize fails and returns from vc_do_resize() and
continues further. At this point console and new frame buffer are mapped
and sets display vars. Despite failure still it continue to proceed
updating the screen at later stages where vc_data is related to previous
frame buffer and frame buffer info and display vars are mapped to new
frame buffer and eventully leading to out-of-bounds write in
fast_imageblit(). This bheviour is excepted only when fg_console is
equal to requested console which is a visible console and updates screen
with invalid struct references in fbcon_putcs().

Reported-and-tested-by: syzbot+c4b7aa0513823e2ea880@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=c4b7aa0513823e2ea880
Signed-off-by: Sravan Kumar Gundu <sravankumarlpu@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Helge Deller <deller@gmx.de>
drivers/video/fbdev/core/fbcon.c

index 2df48037688d1df5a2754d3d8b82f7fc418f6960..e71629618e6a63a8073efb177e18d5877a52bf0d 100644 (file)
@@ -825,7 +825,8 @@ static void con2fb_init_display(struct vc_data *vc, struct fb_info *info,
                                   fg_vc->vc_rows);
        }
 
-       update_screen(vc_cons[fg_console].d);
+       if (fg_console != unit)
+               update_screen(vc_cons[fg_console].d);
 }
 
 /**
@@ -1362,6 +1363,7 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
        struct vc_data *svc;
        struct fbcon_ops *ops = info->fbcon_par;
        int rows, cols;
+       unsigned long ret = 0;
 
        p = &fb_display[unit];
 
@@ -1412,11 +1414,10 @@ static void fbcon_set_disp(struct fb_info *info, struct fb_var_screeninfo *var,
        rows = FBCON_SWAP(ops->rotate, info->var.yres, info->var.xres);
        cols /= vc->vc_font.width;
        rows /= vc->vc_font.height;
-       vc_resize(vc, cols, rows);
+       ret = vc_resize(vc, cols, rows);
 
-       if (con_is_visible(vc)) {
+       if (con_is_visible(vc) && !ret)
                update_screen(vc);
-       }
 }
 
 static __inline__ void ywrap_up(struct vc_data *vc, int count)