All of lore.kernel.org
 help / color / mirror / Atom feed
From: Helge Deller <deller@kernel.org>
To: Jaeyoung Chung <jjy600901@snu.ac.kr>
Cc: deller@gmx.de, dri-devel@lists.freedesktop.org,
	linux-fbdev@vger.kernel.org, simona@ffwll.ch,
	tzimmermann@suse.de, linux-kernel@vger.kernel.org,
	eulgyukim@snu.ac.kr
Subject: Re: [BUG] KASAN: slab-out-of-bounds Read in soft_cursor
Date: Fri, 21 Aug 2026 10:14:00 +0200	[thread overview]
Message-ID: <aogIyAk7AJ-uFP72@carbonx1> (raw)
In-Reply-To: <20260819163440.3702924-1-jjy600901@snu.ac.kr>

* Jaeyoung Chung <jjy600901@snu.ac.kr>:
> Hello,
> 
> We found a "KASAN: slab-out-of-bounds Read in soft_cursor" on Linux v7.2.
> The issue was found by our own race fuzzer. We have not analyzed the root
> cause, so we do not have a proposed fix to offer.
> 
> To reproduce the race reliably, we applied the delay patch below to the
> kernel and ran the C reproducer as root inside an x86_64 QEMU guest. The
> crash log we observed, the delay patch and the reproducer are all included
> below.
> 
> The following kernel config options are required to reproduce the issue:
>     CONFIG_VT=y
>     CONFIG_VT_CONSOLE=y
>     CONFIG_FB=y
>     CONFIG_FB_CORE=y
>     CONFIG_FRAMEBUFFER_CONSOLE=y
>     CONFIG_FRAMEBUFFER_CONSOLE_ROTATION=y
>     CONFIG_FONT_SUPPORT=y
>     CONFIG_FONT_8x16=y
>     CONFIG_DRM=y
>     CONFIG_DRM_BOCHS=y
>     CONFIG_DRM_FBDEV_EMULATION=y
>     CONFIG_KASAN=y
> 
> We hope this report is useful. Please let us know if any further
> information would help.
> 
> Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
> Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr>
> 
> Kernel delay patch:
> ==================================================================
> diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
> index 8f467b22b799..e4d9233c4f5f 100644
> --- a/drivers/tty/vt/vt.c
> +++ b/drivers/tty/vt/vt.c
> @@ -86,6 +86,7 @@
>  #include <linux/major.h>
>  #include <linux/mm.h>
>  #include <linux/console.h>
> +#include <linux/delay.h>
>  #include <linux/init.h>
>  #include <linux/mutex.h>
>  #include <linux/vt_kern.h>
> @@ -4979,6 +4980,9 @@ static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
>  	font.width = op->width;
>  	font.height = op->height;
>  
> +	if (!strncmp(current->comm, "syzrepro", 8) &&
> +	    op->width == 32 && op->height == 30 && op->charcount == 512)
> +		mdelay(100);
>  	guard(console_lock)();
>  
>  	if (vc->vc_mode != KD_TEXT)
> diff --git a/drivers/video/fbdev/core/fbcon_rotate.c b/drivers/video/fbdev/core/fbcon_rotate.c
> index 6cdbc96eeca6..f4797dc2dd78 100644
> --- a/drivers/video/fbdev/core/fbcon_rotate.c
> +++ b/drivers/video/fbdev/core/fbcon_rotate.c
> @@ -9,6 +9,8 @@
>   */
>  
>  #include <linux/errno.h>
> +#include <linux/delay.h>
> +#include <linux/string.h>
>  #include <linux/fb.h>
>  #include <linux/font.h>
>  
> @@ -38,6 +40,9 @@ int fbcon_rotate_font(struct fb_info *info, struct vc_data *vc)
>  		ret = PTR_ERR(buf);
>  		goto err_kfree;
>  	}
> +	if (!strncmp(current->comm, "syzrepro", 8) &&
> +	    par->rotated.bufsize == 4096)
> +		mdelay(50);
>  
>  	par->rotated.buf = buf;
>  
> ==================================================================
> 
> C reproducer:
> ==================================================================
> #define _GNU_SOURCE
> #include <fcntl.h>
> #include <linux/kd.h>
> #include <pthread.h>
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> #include <sys/ioctl.h>
> #include <sys/prctl.h>
> #include <unistd.h>
> 
> #define SYSCHK(x) ({ long __r = (long)(x); if (__r == -1L) { perror(#x); exit(1); } __r; })
> 
> static pthread_barrier_t start;
> static unsigned char font[4U * 32U * 512U];
> 
> static void *rotate_thread(void *arg)
> {
> 	int fd;
> 
> 	prctl(PR_SET_NAME, "syzrepro0", 0, 0, 0);
> 	pthread_barrier_wait(&start);
> 	fd = SYSCHK(open("/sys/class/graphics/fbcon/rotate_all", O_WRONLY));
> 	SYSCHK(write(fd, "1", 1));
> 	close(fd);
> 	return NULL;
> }
> 
> static void *font_thread(void *arg)
> {
> 	struct console_font_op op = { .op = KD_FONT_OP_SET, .width = 32,
> 				      .height = 30, .charcount = 512, .data = font };
> 	int fd;
> 
> 	prctl(PR_SET_NAME, "syzrepro1", 0, 0, 0);
> 	pthread_barrier_wait(&start);
> 	fd = SYSCHK(open("/dev/tty1", O_RDWR | O_NOCTTY));
> 	ioctl(fd, KDFONTOP, &op);
> 	close(fd);
> 	return NULL;
> }
> 
> int main(void)
> {
> 	pthread_t t[2];
> 
> 	memset(font, 0x5a, sizeof(font));
> 	pthread_barrier_init(&start, NULL, 2);
> 	pthread_create(&t[0], NULL, rotate_thread, NULL);
> 	pthread_create(&t[1], NULL, font_thread, NULL);
> 	pthread_join(t[0], NULL);
> 	pthread_join(t[1], NULL);
> 	return 0;
> }
> ==================================================================
> 
> 
> Crash log:
> ==================================================================
> BUG: KASAN: slab-out-of-bounds in soft_cursor+0x3eb/0xb70 drivers/video/fbdev/core/softcursor.c:70
> Read of size 128 at addr ffff88810792d000 by task syzrepro1/401
> 
> CPU: 2 UID: 0 PID: 401 Comm: syzrepro1 Not tainted 7.2.0-dirty #1 PREEMPT 
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.13.0-1ubuntu1.1 04/01/2014
> Call Trace:
>  <TASK>
>  dump_stack_lvl+0x5e/0x80 lib/dump_stack.c:120
>  print_address_description+0x77/0x200 mm/kasan/report.c:378
>  print_report+0x64/0x70 mm/kasan/report.c:482
>  kasan_report+0x118/0x150 mm/kasan/report.c:595
>  check_region_inline mm/kasan/generic.c:-1 [inline]
>  kasan_check_range+0x2b0/0x2c0 mm/kasan/generic.c:200
>  __asan_memcpy+0x29/0x70 mm/kasan/shadow.c:105
>  soft_cursor+0x3eb/0xb70 drivers/video/fbdev/core/softcursor.c:70
>  cw_cursor+0x1322/0x2080 drivers/video/fbdev/core/fbcon_cw.c:324
>  hide_cursor+0x84/0x350 drivers/tty/vt/vt.c:884
>  redraw_screen+0x3b9/0xcb0 drivers/tty/vt/vt.c:986
>  vc_do_resize+0xe4f/0x1490 drivers/tty/vt/vt.c:1310
>  vc_resize include/linux/vt_kern.h:49 [inline]
>  fbcon_do_set_font+0x666/0x1980 drivers/video/fbdev/core/fbcon.c:2435
>  fbcon_set_font+0x50c/0x750 drivers/video/fbdev/core/fbcon.c:2518
>  con_font_set drivers/tty/vt/vt.c:4996 [inline]
>  con_font_op+0x91b/0xdc0 drivers/tty/vt/vt.c:5036
>  vt_k_ioctl drivers/tty/vt/vt_ioctl.c:474 [inline]
>  vt_ioctl+0x719/0x1660 drivers/tty/vt/vt_ioctl.c:745
>  tty_ioctl+0x89c/0xa40 drivers/tty/tty_io.c:2792
>  vfs_ioctl fs/ioctl.c:51 [inline]
>  __do_sys_ioctl fs/ioctl.c:597 [inline]
>  __se_sys_ioctl+0xb6/0x100 fs/ioctl.c:583
>  do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline]
>  do_syscall_64+0xf7/0x370 arch/x86/entry/syscall_64.c:94
>  entry_SYSCALL_64_after_hwframe+0x76/0x7e

I think we need to hide the cursor (in addition to drop the selection).
The position of both may be outside the new screen limits when changing
font sizes.

Can you test the patch below?

Helge


From a383c7ac62d839a94ceb53ad363ccba541165c4a Mon Sep 17 00:00:00 2001
From: Helge Deller <deller@gmx.de>
Date: Fri, 21 Aug 2026 10:01:22 +0200
Subject: [PATCH] vt: hide cursor prior to font changes to avoid out-of-bound
 reads

When changing the size of a sceen font, the amount of columns and rows
on a screen may change and thus the current position of the cursor and
the selection may suddenly lay outside of the current screen limits.
This may lead to slab-out-of-bounds errors as reported by KASAN.

Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr>
Signed-off-by: Helge Deller <deller@gmx.de>
Link: https://lore.kernel.org/all/20260819163440.3702924-1-jjy600901@snu.ac.kr/

diff --git a/drivers/tty/vt/vt.c b/drivers/tty/vt/vt.c
index 8f467b22b799..30c6ea48c338 100644
--- a/drivers/tty/vt/vt.c
+++ b/drivers/tty/vt/vt.c
@@ -4986,8 +4986,8 @@ static int con_font_set(struct vc_data *vc, const struct console_font_op *op)
 	if (!vc->vc_sw->con_font_set)
 		return -ENOSYS;
 
-	if (vc_is_sel(vc))
-		clear_selection();
+	/* hide selection and cursor - due to font size change they might be outside of screen afterwards */
+	hide_cursor(vc);
 
 	return vc->vc_sw->con_font_set(vc, &font, vpitch, op->flags);
 }
@@ -5011,8 +5011,9 @@ static int con_font_default(struct vc_data *vc, struct console_font_op *op)
 		if (!vc->vc_sw->con_font_default)
 			return -ENOSYS;
 
-		if (vc_is_sel(vc))
-			clear_selection();
+		/* hide selection and cursor - due to font size change they might be outside of screen afterwards */
+		hide_cursor(vc);
+
 		int ret = vc->vc_sw->con_font_default(vc, &font, s);
 		if (ret)
 			return ret;


      parent reply	other threads:[~2026-08-21  8:14 UTC|newest]

Thread overview: 3+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-08-19 16:34 [BUG] KASAN: slab-out-of-bounds Read in soft_cursor Jaeyoung Chung
2026-08-19 16:57 ` sashiko-bot
2026-08-21  8:14 ` Helge Deller [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aogIyAk7AJ-uFP72@carbonx1 \
    --to=deller@kernel.org \
    --cc=deller@gmx.de \
    --cc=dri-devel@lists.freedesktop.org \
    --cc=eulgyukim@snu.ac.kr \
    --cc=jjy600901@snu.ac.kr \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=simona@ffwll.ch \
    --cc=tzimmermann@suse.de \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.