From 5b97eebcce1b4f3f07a71f635d6aa3af96c236e7 Mon Sep 17 00:00:00 2001 From: Qianqiang Liu Date: Wed, 25 Sep 2024 13:29:36 +0800 Subject: [PATCH 1/4] fbcon: Fix a NULL pointer dereference issue in fbcon_putcs syzbot has found a NULL pointer dereference bug in fbcon. Here is the simplified C reproducer: struct param { uint8_t type; struct tiocl_selection ts; }; int main() { struct fb_con2fbmap con2fb; struct param param; int fd = open("/dev/fb1", 0, 0); con2fb.console = 0x19; con2fb.framebuffer = 0; ioctl(fd, FBIOPUT_CON2FBMAP, &con2fb); param.type = 2; param.ts.xs = 0; param.ts.ys = 0; param.ts.xe = 0; param.ts.ye = 0; param.ts.sel_mode = 0; int fd1 = open("/dev/tty1", O_RDWR, 0); ioctl(fd1, TIOCLINUX, ¶m); con2fb.console = 1; con2fb.framebuffer = 0; ioctl(fd, FBIOPUT_CON2FBMAP, &con2fb); return 0; } After calling ioctl(fd1, TIOCLINUX, ¶m), the subsequent ioctl(fd, FBIOPUT_CON2FBMAP, &con2fb) causes the kernel to follow a different execution path: set_con2fb_map -> con2fb_init_display -> fbcon_set_disp -> redraw_screen -> hide_cursor -> clear_selection -> highlight -> invert_screen -> do_update_region -> fbcon_putcs -> ops->putcs Since ops->putcs is a NULL pointer, this leads to a kernel panic. To prevent this, we need to call set_blitting_type() within set_con2fb_map() to properly initialize ops->putcs. Reported-by: syzbot+3d613ae53c031502687a@syzkaller.appspotmail.com Closes: https://syzkaller.appspot.com/bug?extid=3d613ae53c031502687a Tested-by: syzbot+3d613ae53c031502687a@syzkaller.appspotmail.com Signed-off-by: Qianqiang Liu Signed-off-by: Helge Deller --- drivers/video/fbdev/core/fbcon.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index 2e093535884b..d9abae2516d8 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -861,6 +861,8 @@ static int set_con2fb_map(int unit, int newidx, int user) return err; fbcon_add_cursor_work(info); + } else if (vc) { + set_blitting_type(vc, info); } con2fb_map[unit] = newidx; From f1ebbe4cd07d058f42174cc5b8c5efcf83de8ffa Mon Sep 17 00:00:00 2001 From: Markus Elfring Date: Wed, 25 Sep 2024 21:12:36 +0200 Subject: [PATCH 2/4] fbdev: omapfb: Call of_node_put(ep) only once in omapdss_of_find_source_for_first_ep() An of_node_put(ep) call was immediately used after a pointer check for a of_graph_get_remote_port() call in this function implementation. Thus call such a function only once instead directly before the check. This issue was transformed by using the Coccinelle software. Signed-off-by: Markus Elfring Signed-off-by: Helge Deller --- drivers/video/fbdev/omap2/omapfb/dss/dss-of.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c index 4040e247e026..d5a43b3bf45e 100644 --- a/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c +++ b/drivers/video/fbdev/omap2/omapfb/dss/dss-of.c @@ -129,12 +129,9 @@ omapdss_of_find_source_for_first_ep(struct device_node *node) return ERR_PTR(-EINVAL); src_port = of_graph_get_remote_port(ep); - if (!src_port) { - of_node_put(ep); - return ERR_PTR(-EINVAL); - } - of_node_put(ep); + if (!src_port) + return ERR_PTR(-EINVAL); src = omap_dss_find_output_by_port_node(src_port); From 2555906fd53e0a5239431d44fad695b420e94fdd Mon Sep 17 00:00:00 2001 From: Qianqiang Liu Date: Thu, 26 Sep 2024 19:59:11 +0800 Subject: [PATCH 3/4] fbcon: break earlier in search_fb_in_map and search_for_mapped_con Break the for loop immediately upon finding the target, making the process more efficient. Signed-off-by: Qianqiang Liu Signed-off-by: Helge Deller --- drivers/video/fbdev/core/fbcon.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/drivers/video/fbdev/core/fbcon.c b/drivers/video/fbdev/core/fbcon.c index d9abae2516d8..e8b4e8c119b5 100644 --- a/drivers/video/fbdev/core/fbcon.c +++ b/drivers/video/fbdev/core/fbcon.c @@ -512,8 +512,10 @@ static int search_fb_in_map(int idx) int i, retval = 0; for (i = first_fb_vc; i <= last_fb_vc; i++) { - if (con2fb_map[i] == idx) + if (con2fb_map[i] == idx) { retval = 1; + break; + } } return retval; } @@ -523,8 +525,10 @@ static int search_for_mapped_con(void) int i, retval = 0; for (i = first_fb_vc; i <= last_fb_vc; i++) { - if (con2fb_map[i] != -1) + if (con2fb_map[i] != -1) { retval = 1; + break; + } } return retval; } From 9cf14f5a2746c19455ce9cb44341b5527b5e19c3 Mon Sep 17 00:00:00 2001 From: Andrey Shumilin Date: Fri, 27 Sep 2024 22:34:24 +0300 Subject: [PATCH 4/4] fbdev: sisfb: Fix strbuf array overflow The values of the variables xres and yres are placed in strbuf. These variables are obtained from strbuf1. The strbuf1 array contains digit characters and a space if the array contains non-digit characters. Then, when executing sprintf(strbuf, "%ux%ux8", xres, yres); more than 16 bytes will be written to strbuf. It is suggested to increase the size of the strbuf array to 24. Found by Linux Verification Center (linuxtesting.org) with SVACE. Signed-off-by: Andrey Shumilin Signed-off-by: Helge Deller --- drivers/video/fbdev/sis/sis_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/fbdev/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c index 009bf1d92644..75033e6be15a 100644 --- a/drivers/video/fbdev/sis/sis_main.c +++ b/drivers/video/fbdev/sis/sis_main.c @@ -183,7 +183,7 @@ static void sisfb_search_mode(char *name, bool quiet) { unsigned int j = 0, xres = 0, yres = 0, depth = 0, rate = 0; int i = 0; - char strbuf[16], strbuf1[20]; + char strbuf[24], strbuf1[20]; char *nameptr = name; /* We don't know the hardware specs yet and there is no ivideo */