linux-fbdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* KASAN: use-after-free Read in bit_putcs
@ 2020-02-23 17:30 syzbot
  2020-09-26  2:03 ` syzbot
  0 siblings, 1 reply; 18+ messages in thread
From: syzbot @ 2020-02-23 17:30 UTC (permalink / raw)
  To: b.zolnierkie, dri-devel, linux-fbdev, linux-kernel, syzkaller-bugs

Hello,

syzbot found the following crash on:

HEAD commit:    0a44cac8 Merge tag 'dma-mapping-5.6' of git://git.infradea..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x\x11bfb74ee00000
kernel config:  https://syzkaller.appspot.com/x/.config?x¦1f2164c515c07f
dashboard link: https://syzkaller.appspot.com/bug?extid³08f5fd049fbbc6e74f
compiler:       clang version 10.0.0 (https://github.com/llvm/llvm-project/ c2443155a0fb245c8f17f2c1c72b6ea391e86e81)

Unfortunately, I don't have any reproducer for this crash yet.

IMPORTANT: if you fix the bug, please add the following tag to the commit:
Reported-by: syzbot+b308f5fd049fbbc6e74f@syzkaller.appspotmail.com

=================================
BUG: KASAN: use-after-free in __fb_pad_aligned_buffer include/linux/fb.h:655 [inline]
BUG: KASAN: use-after-free in bit_putcs_aligned drivers/video/fbdev/core/bitblit.c:96 [inline]
BUG: KASAN: use-after-free in bit_putcs+0x13ee/0x1cc0 drivers/video/fbdev/core/bitblit.c:185
Read of size 1 at addr ffff8880a8087c10 by task syz-executor.2/5278

CPU: 1 PID: 5278 Comm: syz-executor.2 Not tainted 5.6.0-rc2-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x1fb/0x318 lib/dump_stack.c:118
 print_address_description+0x74/0x5c0 mm/kasan/report.c:374
 __kasan_report+0x149/0x1c0 mm/kasan/report.c:506
 kasan_report+0x26/0x50 mm/kasan/common.c:641
 __asan_report_load1_noabort+0x14/0x20 mm/kasan/generic_report.c:132
 __fb_pad_aligned_buffer include/linux/fb.h:655 [inline]
 bit_putcs_aligned drivers/video/fbdev/core/bitblit.c:96 [inline]
 bit_putcs+0x13ee/0x1cc0 drivers/video/fbdev/core/bitblit.c:185
 fbcon_putcs+0x7b4/0xad0 drivers/video/fbdev/core/fbcon.c:1360
 do_update_region+0x462/0x600 drivers/tty/vt/vt.c:677
 redraw_screen+0xcc5/0x1830 drivers/tty/vt/vt.c:1011
 vc_do_resize+0x12af/0x1af0 drivers/tty/vt/vt.c:1284
 vc_resize+0x4f/0x60 drivers/tty/vt/vt.c:1304
 vt_ioctl+0x2fa8/0x3a70 drivers/tty/vt/vt_ioctl.c:887
 tty_ioctl+0xee6/0x15c0 drivers/tty/tty_io.c:2660
 vfs_ioctl fs/ioctl.c:47 [inline]
 ksys_ioctl fs/ioctl.c:763 [inline]
 __do_sys_ioctl fs/ioctl.c:772 [inline]
 __se_sys_ioctl+0x113/0x190 fs/ioctl.c:770
 __x64_sys_ioctl+0x7b/0x90 fs/ioctl.c:770
 do_syscall_64+0xf7/0x1c0 arch/x86/entry/common.c:294
 entry_SYSCALL_64_after_hwframe+0x49/0xbe
RIP: 0033:0x45c449
Code: ad b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00 00 66 90 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 7b b6 fb ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007f74261f2c78 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
RAX: ffffffffffffffda RBX: 00007f74261f36d4 RCX: 000000000045c449
RDX: 0000000020000080 RSI: 000000000000560a RDI: 0000000000000003
RBP: 000000000076bf20 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00000000ffffffff
R13: 000000000000066b R14: 00000000004c8fe0 R15: 000000000076bf2c

Allocated by task 2919:
 save_stack mm/kasan/common.c:72 [inline]
 set_track mm/kasan/common.c:80 [inline]
 __kasan_kmalloc+0x118/0x1c0 mm/kasan/common.c:515
 kasan_kmalloc+0x9/0x10 mm/kasan/common.c:529
 __do_kmalloc_node mm/slab.c:3616 [inline]
 __kmalloc_node_track_caller+0x4d/0x60 mm/slab.c:3630
 __kmalloc_reserve net/core/skbuff.c:142 [inline]
 __alloc_skb+0xe8/0x500 net/core/skbuff.c:210
 alloc_skb include/linux/skbuff.h:1051 [inline]
 _sctp_make_chunk+0x60/0x460 net/sctp/sm_make_chunk.c:1394
 sctp_make_data net/sctp/sm_make_chunk.c:1426 [inline]
 sctp_make_datafrag_empty+0xa3/0x5b0 net/sctp/sm_make_chunk.c:740
 sctp_datamsg_from_user+0x7a8/0x1020 net/sctp/chunk.c:262
 sctp_sendmsg_to_asoc+0x7a9/0x1500 net/sctp/socket.c:1844
 sctp_sendmsg+0x15a1/0x3570 net/sctp/socket.c:2016
 inet_sendmsg+0x147/0x310 net/ipv4/af_inet.c:807
 sock_sendmsg_nosec net/socket.c:652 [inline]
 sock_sendmsg net/socket.c:672 [inline]
 ____sys_sendmsg+0x4f7/0x7f0 net/socket.c:2343
 ___sys_sendmsg net/socket.c:2397 [inline]
 __sys_sendmsg+0x1ed/0x290 net/socket.c:2430
 __do_sys_sendmsg net/socket.c:2439 [inline]
 __se_sys_sendmsg net/socket.c:2437 [inline]
 __x64_sys_sendmsg+0x7f/0x90 net/socket.c:2437
 do_syscall_64+0xf7/0x1c0 arch/x86/entry/common.c:294
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

Freed by task 2919:
 save_stack mm/kasan/common.c:72 [inline]
 set_track mm/kasan/common.c:80 [inline]
 kasan_set_free_info mm/kasan/common.c:337 [inline]
 __kasan_slab_free+0x12e/0x1e0 mm/kasan/common.c:476
 kasan_slab_free+0xe/0x10 mm/kasan/common.c:485
 __cache_free mm/slab.c:3426 [inline]
 kfree+0x10d/0x220 mm/slab.c:3757
 skb_free_head net/core/skbuff.c:592 [inline]
 skb_release_data+0x72f/0x8c0 net/core/skbuff.c:612
 skb_release_all net/core/skbuff.c:666 [inline]
 __kfree_skb+0x59/0x1c0 net/core/skbuff.c:680
 consume_skb+0x72/0x110 net/core/skbuff.c:839
 sctp_chunk_destroy net/sctp/sm_make_chunk.c:1454 [inline]
 sctp_chunk_put+0x17b/0x200 net/sctp/sm_make_chunk.c:1481
 sctp_chunk_free+0x59/0x60 net/sctp/sm_make_chunk.c:1468
 sctp_outq_sack+0x1169/0x16a0 net/sctp/outqueue.c:1352
 sctp_cmd_process_sack net/sctp/sm_sideeffect.c:798 [inline]
 sctp_cmd_interpreter net/sctp/sm_sideeffect.c:1354 [inline]
 sctp_side_effects net/sctp/sm_sideeffect.c:1185 [inline]
 sctp_do_sm+0x18f3/0x5840 net/sctp/sm_sideeffect.c:1156
 sctp_assoc_bh_rcv+0x494/0x770 net/sctp/associola.c:1044
 sctp_inq_push+0x1ab/0x1d0 net/sctp/inqueue.c:80
 sctp_backlog_rcv+0x16c/0x4b0 net/sctp/input.c:344
 sk_backlog_rcv include/net/sock.h:938 [inline]
 __release_sock+0x1c1/0x4b0 net/core/sock.c:2437
 release_sock+0x65/0x1c0 net/core/sock.c:2953
 sctp_wait_for_connect+0x2f6/0x590 net/sctp/socket.c:9280
 sctp_sendmsg_to_asoc+0x11ba/0x1500 net/sctp/socket.c:1870
 sctp_sendmsg+0x15a1/0x3570 net/sctp/socket.c:2016
 inet_sendmsg+0x147/0x310 net/ipv4/af_inet.c:807
 sock_sendmsg_nosec net/socket.c:652 [inline]
 sock_sendmsg net/socket.c:672 [inline]
 ____sys_sendmsg+0x4f7/0x7f0 net/socket.c:2343
 ___sys_sendmsg net/socket.c:2397 [inline]
 __sys_sendmsg+0x1ed/0x290 net/socket.c:2430
 __do_sys_sendmsg net/socket.c:2439 [inline]
 __se_sys_sendmsg net/socket.c:2437 [inline]
 __x64_sys_sendmsg+0x7f/0x90 net/socket.c:2437
 do_syscall_64+0xf7/0x1c0 arch/x86/entry/common.c:294
 entry_SYSCALL_64_after_hwframe+0x49/0xbe

The buggy address belongs to the object at ffff8880a8087c00
 which belongs to the cache kmalloc-512 of size 512
The buggy address is located 16 bytes inside of
 512-byte region [ffff8880a8087c00, ffff8880a8087e00)
The buggy address belongs to the page:
page:ffffea0002a021c0 refcount:1 mapcount:0 mapping:ffff8880aa400a80 index:0x0
flags: 0xfffe0000000200(slab)
raw: 00fffe0000000200 ffffea0002431688 ffffea000259d648 ffff8880aa400a80
raw: 0000000000000000 ffff8880a8087000 0000000100000004 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff8880a8087b00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff8880a8087b80: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
>ffff8880a8087c00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                         ^
 ffff8880a8087c80: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff8880a8087d00: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
=================================


---
This bug is generated by a bot. It may contain errors.
See https://goo.gl/tpsmEJ for more information about syzbot.
syzbot engineers can be reached at syzkaller@googlegroups.com.

syzbot will keep track of this bug report. See:
https://goo.gl/tpsmEJ#status for how to communicate with syzbot.

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: KASAN: use-after-free Read in bit_putcs
  2020-02-23 17:30 KASAN: use-after-free Read in bit_putcs syzbot
@ 2020-09-26  2:03 ` syzbot
  2020-09-26 16:25   ` Tetsuo Handa
  0 siblings, 1 reply; 18+ messages in thread
From: syzbot @ 2020-09-26  2:03 UTC (permalink / raw)
  To: b.zolnierkie, daniel.vetter, deller, dri-devel, gregkh,
	jirislaby, linux-fbdev, linux-kernel, penguin-kernel,
	syzkaller-bugs

syzbot has found a reproducer for the following issue on:

HEAD commit:    171d4ff7 Merge tag 'mmc-v5.9-rc4-2' of git://git.kernel.or..
git tree:       upstream
console output: https://syzkaller.appspot.com/x/log.txt?x\x13b41d03900000
kernel config:  https://syzkaller.appspot.com/x/.config?x$0e2ebab67245c7
dashboard link: https://syzkaller.appspot.com/bug?extid³08f5fd049fbbc6e74f
compiler:       gcc (GCC) 10.1.0-syz 20200507
syz repro:      https://syzkaller.appspot.com/x/repro.syz?x\x143d11d3900000
C reproducer:   https://syzkaller.appspot.com/x/repro.c?x\x150d16e5900000

IMPORTANT: if you fix the issue, please add the following tag to the commit:
Reported-by: syzbot+b308f5fd049fbbc6e74f@syzkaller.appspotmail.com

=================================
BUG: KASAN: use-after-free in __fb_pad_aligned_buffer include/linux/fb.h:654 [inline]
BUG: KASAN: use-after-free in bit_putcs_aligned drivers/video/fbdev/core/bitblit.c:96 [inline]
BUG: KASAN: use-after-free in bit_putcs+0xbb6/0xd20 drivers/video/fbdev/core/bitblit.c:185
Read of size 1 at addr ffff88809df498fe by task syz-executor859/6860

CPU: 1 PID: 6860 Comm: syz-executor859 Not tainted 5.9.0-rc6-syzkaller #0
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011
Call Trace:
 __dump_stack lib/dump_stack.c:77 [inline]
 dump_stack+0x198/0x1fd lib/dump_stack.c:118
 print_address_description.constprop.0.cold+0xae/0x497 mm/kasan/report.c:383
 __kasan_report mm/kasan/report.c:513 [inline]
 kasan_report.cold+0x1f/0x37 mm/kasan/report.c:530
 __fb_pad_aligned_buffer include/linux/fb.h:654 [inline]
 bit_putcs_aligned drivers/video/fbdev/core/bitblit.c:96 [inline]
 bit_putcs+0xbb6/0xd20 drivers/video/fbdev/core/bitblit.c:185
 fbcon_putcs+0x35a/0x450 drivers/video/fbdev/core/fbcon.c:1308
 con_flush drivers/tty/vt/vt.c:2575 [inline]
 do_con_write+0xb6b/0x1dd0 drivers/tty/vt/vt.c:2905
 con_write+0x22/0xb0 drivers/tty/vt/vt.c:3250
 process_output_block drivers/tty/n_tty.c:595 [inline]
 n_tty_write+0x3ce/0xf80 drivers/tty/n_tty.c:2333
 do_tty_write drivers/tty/tty_io.c:962 [inline]
 tty_write+0x4d9/0x870 drivers/tty/tty_io.c:1046
 vfs_write+0x2b0/0x730 fs/read_write.c:576
 ksys_write+0x12d/0x250 fs/read_write.c:631
 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x44/0xa9
RIP: 0033:0x4403c9
Code: 18 89 d0 c3 66 2e 0f 1f 84 00 00 00 00 00 0f 1f 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 0f 83 db 13 fc ff c3 66 2e 0f 1f 84 00 00 00 00
RSP: 002b:00007ffd97e140c8 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 00000000004002c8 RCX: 00000000004403c9
RDX: 0000000000001006 RSI: 0000000020000180 RDI: 0000000000000006
RBP: 00000000006cb018 R08: 00000000004002c8 R09: 00000000004002c8
R10: 000000000000000d R11: 0000000000000246 R12: 0000000000401c30
R13: 0000000000401cc0 R14: 0000000000000000 R15: 0000000000000000

Allocated by task 6860:
 kasan_save_stack+0x1b/0x40 mm/kasan/common.c:48
 kasan_set_track mm/kasan/common.c:56 [inline]
 __kasan_kmalloc.constprop.0+0xbf/0xd0 mm/kasan/common.c:461
 __do_kmalloc mm/slab.c:3655 [inline]
 __kmalloc+0x1b0/0x360 mm/slab.c:3664
 kmalloc include/linux/slab.h:559 [inline]
 kzalloc include/linux/slab.h:666 [inline]
 tomoyo_init_log+0x1376/0x1ee0 security/tomoyo/audit.c:275
 tomoyo_supervisor+0x34d/0xef0 security/tomoyo/common.c:2097
 tomoyo_audit_env_log security/tomoyo/environ.c:36 [inline]
 tomoyo_env_perm+0x17f/0x1f0 security/tomoyo/environ.c:63
 tomoyo_environ security/tomoyo/domain.c:674 [inline]
 tomoyo_find_next_domain+0x1438/0x1f77 security/tomoyo/domain.c:881
 tomoyo_bprm_check_security security/tomoyo/tomoyo.c:101 [inline]
 tomoyo_bprm_check_security+0x121/0x1a0 security/tomoyo/tomoyo.c:91
 security_bprm_check+0x45/0xa0 security/security.c:840
 search_binary_handler fs/exec.c:1807 [inline]
 exec_binprm fs/exec.c:1860 [inline]
 bprm_execve+0x879/0x1b10 fs/exec.c:1931
 do_execveat_common+0x626/0x7c0 fs/exec.c:2026
 do_execve fs/exec.c:2094 [inline]
 __do_sys_execve fs/exec.c:2170 [inline]
 __se_sys_execve fs/exec.c:2165 [inline]
 __x64_sys_execve+0x8f/0xc0 fs/exec.c:2165
 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x44/0xa9

Freed by task 6860:
 kasan_save_stack+0x1b/0x40 mm/kasan/common.c:48
 kasan_set_track+0x1c/0x30 mm/kasan/common.c:56
 kasan_set_free_info+0x1b/0x30 mm/kasan/generic.c:355
 __kasan_slab_free+0xd8/0x120 mm/kasan/common.c:422
 __cache_free mm/slab.c:3418 [inline]
 kfree+0x10e/0x2b0 mm/slab.c:3756
 tomoyo_supervisor+0x36e/0xef0 security/tomoyo/common.c:2149
 tomoyo_audit_env_log security/tomoyo/environ.c:36 [inline]
 tomoyo_env_perm+0x17f/0x1f0 security/tomoyo/environ.c:63
 tomoyo_environ security/tomoyo/domain.c:674 [inline]
 tomoyo_find_next_domain+0x1438/0x1f77 security/tomoyo/domain.c:881
 tomoyo_bprm_check_security security/tomoyo/tomoyo.c:101 [inline]
 tomoyo_bprm_check_security+0x121/0x1a0 security/tomoyo/tomoyo.c:91
 security_bprm_check+0x45/0xa0 security/security.c:840
 search_binary_handler fs/exec.c:1807 [inline]
 exec_binprm fs/exec.c:1860 [inline]
 bprm_execve+0x879/0x1b10 fs/exec.c:1931
 do_execveat_common+0x626/0x7c0 fs/exec.c:2026
 do_execve fs/exec.c:2094 [inline]
 __do_sys_execve fs/exec.c:2170 [inline]
 __se_sys_execve fs/exec.c:2165 [inline]
 __x64_sys_execve+0x8f/0xc0 fs/exec.c:2165
 do_syscall_64+0x2d/0x70 arch/x86/entry/common.c:46
 entry_SYSCALL_64_after_hwframe+0x44/0xa9

The buggy address belongs to the object at ffff88809df49800
 which belongs to the cache kmalloc-1k of size 1024
The buggy address is located 254 bytes inside of
 1024-byte region [ffff88809df49800, ffff88809df49c00)
The buggy address belongs to the page:
page:000000001b295380 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0x9df49
flags: 0xfffe0000000200(slab)
raw: 00fffe0000000200 ffffea00027dc7c8 ffff8880aa041850 ffff8880aa040700
raw: 0000000000000000 ffff88809df49000 0000000100000002 0000000000000000
page dumped because: kasan: bad access detected

Memory state around the buggy address:
 ffff88809df49780: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
 ffff88809df49800: fa fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
>ffff88809df49880: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
                                                                ^
 ffff88809df49900: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
 ffff88809df49980: fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb fb
=================================

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: KASAN: use-after-free Read in bit_putcs
  2020-09-26  2:03 ` syzbot
@ 2020-09-26 16:25   ` Tetsuo Handa
  2020-09-26 19:39     ` Peilin Ye
  2020-09-27  0:25     ` Tetsuo Handa
  0 siblings, 2 replies; 18+ messages in thread
From: Tetsuo Handa @ 2020-09-26 16:25 UTC (permalink / raw)
  To: syzbot, b.zolnierkie, daniel.vetter, deller, gregkh, jirislaby,
	syzkaller-bugs
  Cc: linux-fbdev, linux-kernel, dri-devel

A simplified reproducer and debug printk() patch shown below reported that
vc_font.height is increased to 9 via ioctl(VT_RESIZEX) after it was once
decreased from 16 to 2 via ioctl(PIO_FONT).



Since vc_resize() with v.v_rows = 0 preserves current vc->vc_rows value,
this reproducer is bypassing

	if (v.v_clin) {
		int rows = v.v_vlin / v.v_clin;
		if (v.v_rows != rows) {
			if (v.v_rows) /* Parameters don't add up */
				return -EINVAL;
			v.v_rows = rows;
		}
	}

check by setting v.v_vlin = 1 and v.v_clin = 9.

If v.v_vcol > 0 and v.v_vcol != vc->vc_cols (though this reproducer is passing
v.v_vcol = 0), tty_do_resize() from vc_do_resize() from vc_resize() can make
"struct tty_struct"->winsize.ws_ypixel = 1 despite
"struct tty_struct"->winsize.vc->vc_rows = vc->vc_rows (which is usually larger
than 1). Does such winsize (a row has 1 / vc->vc_rows pixel) make sense?



Since I don't know the meaning of "struct vt_consize"->v_clin (which is commented
with "/* number of pixel rows per character */" but does it mean font size ?),
I don't know why we can assign that value to vcp->vc_font.height via

	if (v.v_clin)
		vcp->vc_font.height = v.v_clin;

in vt_resizex(). While ioctl(PIO_FONT) needs to pass vc->vc_sw->con_font_set()
check in con_font_set(), ioctl(VT_RESIZEX) does not pass it in vt_resizex()...

Since this problem does not happen if I remove

	if (v.v_clin)
		vcp->vc_font.height = v.v_clin;

 from vt_resizex(), I guess that some variables are getting confused by change
of vc->vc_font.height ...

  #define VT_RESIZE     0x5609  /* set kernel's idea of screensize */
  #define VT_RESIZEX    0x560A  /* set kernel's idea of screensize + more */

Hmm, what comes to the "+ more" part? Who is using VT_RESIZEX ?
If nobody is using VT_RESIZEX, better to make VT_RESIZEX = VT_RESIZE ?

----------
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <linux/kd.h>
#include <linux/vt.h>

int main(int argc, char *argv[])
{
        int fd = open("/dev/tty1", 3);
        static char fontdata[8192] = { 2, 3 };
        struct vt_consize v_c = { 0, 0, 1, 9, 0, 0 };
        ioctl(fd, PIO_FONT, fontdata);
        ioctl(fd, VT_RESIZEX, &v_c);
        return 0;
}
----------

----------
diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index a4e520bdd521..df6b7abd1068 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -769,64 +769,70 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
 {
 	struct vt_consize v;
 	int i;
+	int ret = 0;
 
 	if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
 		return -EFAULT;
 
-	/* FIXME: Should check the copies properly */
-	if (!v.v_vlin)
-		v.v_vlin = vc->vc_scan_lines;
+	console_lock();
+	for (i = 0; i < MAX_NR_CONSOLES; i++) {
+		struct vc_data *vcp = vc_cons[i].d;
 
-	if (v.v_clin) {
-		int rows = v.v_vlin / v.v_clin;
-		if (v.v_rows != rows) {
-			if (v.v_rows) /* Parameters don't add up */
-				return -EINVAL;
-			v.v_rows = rows;
+		if (!vcp)
+			continue;
+		if (v.v_clin) {
+			int rows = (v.v_vlin ? v.v_vlin : vcp->vc_scan_lines) / v.v_clin;
+			if (v.v_rows != rows) {
+				if (v.v_rows) { /* Parameters don't add up */
+					ret = -EINVAL;
+					break;
+				}
+				v.v_rows = rows;
+			}
 		}
-	}
-
-	if (v.v_vcol && v.v_ccol) {
-		int cols = v.v_vcol / v.v_ccol;
-		if (v.v_cols != cols) {
-			if (v.v_cols)
-				return -EINVAL;
-			v.v_cols = cols;
+		if (v.v_vcol && v.v_ccol) {
+			int cols = v.v_vcol / v.v_ccol;
+			if (v.v_cols != cols) {
+				if (v.v_cols) {
+					ret = -EINVAL;
+					break;
+				}
+				v.v_cols = cols;
+			}
+		}
+		if (v.v_clin > 32) {
+			ret = -EINVAL;
+			break;
 		}
 	}
+	printk(KERN_INFO "vc=%px v.v_rows=%hu v.v_cols=%hu v.v_vlin=%hu v.v_clin=%u v.v_vcol=%hu v.v_ccol=%hu ret=%d\n", vc, v.v_rows, v.v_cols, v.v_vlin, v.v_clin, v.v_vcol, v.v_ccol, ret);
+	for (i = 0; !ret && i < MAX_NR_CONSOLES; i++) {
+		unsigned int save_scan_lines;
+		unsigned int save_font_height;
+		struct vc_data *vcp = vc_cons[i].d;
 
-	if (v.v_clin > 32)
-		return -EINVAL;
-
-	for (i = 0; i < MAX_NR_CONSOLES; i++) {
-		struct vc_data *vcp;
-
-		if (!vc_cons[i].d)
+		if (!vcp)
 			continue;
-		console_lock();
-		vcp = vc_cons[i].d;
-		if (vcp) {
-			int ret;
-			int save_scan_lines = vcp->vc_scan_lines;
-			int save_font_height = vcp->vc_font.height;
-
-			if (v.v_vlin)
-				vcp->vc_scan_lines = v.v_vlin;
-			if (v.v_clin)
-				vcp->vc_font.height = v.v_clin;
-			vcp->vc_resize_user = 1;
-			ret = vc_resize(vcp, v.v_cols, v.v_rows);
-			if (ret) {
-				vcp->vc_scan_lines = save_scan_lines;
-				vcp->vc_font.height = save_font_height;
-				console_unlock();
-				return ret;
-			}
+		save_scan_lines = vcp->vc_scan_lines;
+		save_font_height = vcp->vc_font.height;
+		if (v.v_vlin)
+			vcp->vc_scan_lines = v.v_vlin;
+		if (v.v_clin)
+			vcp->vc_font.height = v.v_clin;
+		printk(KERN_INFO "vcp=%px before: ->vc_rows=%u ->vc_cols=%u ->vc_scan_lines=%u save_scan_lines=%u ->vc_font.height=%u save_font_height=%u\n",
+		       vcp, vcp->vc_rows, vcp->vc_cols, vcp->vc_scan_lines, save_scan_lines, vcp->vc_font.height, save_font_height);
+		vcp->vc_resize_user = 1;
+		ret = vc_resize(vcp, v.v_cols, v.v_rows);
+		printk(KERN_INFO "vcp=%px after: ->vc_rows=%u ->vc_cols=%u ->vc_scan_lines=%u save_scan_lines=%u ->vc_font.height=%u save_font_height=%u ret=%d\n",
+		       vcp, vcp->vc_rows, vcp->vc_cols, vcp->vc_scan_lines, save_scan_lines, vcp->vc_font.height, save_font_height, ret);
+		if (ret) {
+			vcp->vc_scan_lines = save_scan_lines;
+			vcp->vc_font.height = save_font_height;
 		}
-		console_unlock();
 	}
+	console_unlock();
 
-	return 0;
+	return ret;
 }
 
 /*
diff --git a/drivers/video/fbdev/core/bitblit.c b/drivers/video/fbdev/core/bitblit.c
index 9725ecd1255b..c1b9f43ff657 100644
--- a/drivers/video/fbdev/core/bitblit.c
+++ b/drivers/video/fbdev/core/bitblit.c
@@ -181,6 +181,8 @@ static void bit_putcs(struct vc_data *vc, struct fb_info *info,
 		dst = fb_get_buffer_offset(info, &info->pixmap, size);
 		image.data = dst;
 
+		printk(KERN_DEBUG "%s: width=%u cellsize=%u count=%d maxcnt=%u scan_align=%u buf_align=%u image.width=%u image.height=%u pitch=%u\n",
+		       __func__, width, cellsize, count, maxcnt, scan_align, buf_align, image.width, image.height, pitch);
 		if (!mod)
 			bit_putcs_aligned(vc, info, s, attribute, cnt, pitch,
 					  width, cellsize, &image, buf, dst);
----------

----------
[  297.298013] [ T2823] bit_putcs: width=1 cellsize\x16 count€ maxcntQ2 scan_align=0 buf_align=0 image.widthd0 image.height\x16 pitch€
[  297.312092] [ T2823] bit_putcs: width=1 cellsize\x16 count€ maxcntQ2 scan_align=0 buf_align=0 image.widthd0 image.height\x16 pitch€
[  297.324735] [ T2823] bit_putcs: width=1 cellsize\x16 count€ maxcntQ2 scan_align=0 buf_align=0 image.widthd0 image.height\x16 pitch€
[  297.337634] [ T2823] bit_putcs: width=1 cellsize\x16 count€ maxcntQ2 scan_align=0 buf_align=0 image.widthd0 image.height\x16 pitch€
[  297.350185] [ T2823] bit_putcs: width=1 cellsize\x16 count€ maxcntQ2 scan_align=0 buf_align=0 image.widthd0 image.height\x16 pitch€
[  297.361861] [ T2823] bit_putcs: width=1 cellsize\x16 count€ maxcntQ2 scan_align=0 buf_align=0 image.widthd0 image.height\x16 pitch€
[  297.474116] [ T2823] bit_putcs: width=1 cellsize\x16 count( maxcntQ2 scan_align=0 buf_align=0 image.width"4 image.height\x16 pitch(
[  297.481866] [ T2823] bit_putcs: width=1 cellsize\x16 count=4 maxcntQ2 scan_align=0 buf_align=0 image.width2 image.height\x16 pitch=4
[  297.483529] [ T2823] bit_putcs: width=1 cellsize\x16 count=1 maxcntQ2 scan_align=0 buf_align=0 image.width=8 image.height\x16 pitch=1
[  297.484792] [ T2823] bit_putcs: width=1 cellsize\x16 count=7 maxcntQ2 scan_align=0 buf_align=0 image.widthV image.height\x16 pitch=7
[  357.373828] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.375232] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.376821] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.378256] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.379684] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
(...snipped...)
[  357.720089] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.721519] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.722962] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.724390] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.725834] [ T2940] bit_putcs: width=1 cellsize=2 count€ maxcnt@96 scan_align=0 buf_align=0 image.widthd0 image.height=2 pitch€
[  357.727876] [ T2940] vcÿff8880d69b6000 v.v_rows=0 v.v_cols=0 v.v_vlin=1 v.v_clin=9 v.v_vcol=0 v.v_ccol=0 ret=0
[  357.727933] [ T2940] vcpÿff8880d69b6000 before: ->vc_rows$0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height=2
[  357.727994] [ T2940] vcpÿff8880d69b6000 after: ->vc_rows$0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height=2 ret=0
[  357.728050] [ T2940] vcpÿff8880d46d9000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  357.728110] [ T2940] vcpÿff8880d46d9000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  357.728167] [ T2940] vcpÿff8880d40a8000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  357.728227] [ T2940] vcpÿff8880d40a8000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  357.728283] [ T2940] vcpÿff8880d46fb000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  357.728344] [ T2940] vcpÿff8880d46fb000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  357.728400] [ T2940] vcpÿff8880d46f9000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  357.728460] [ T2940] vcpÿff8880d46f9000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  357.728516] [ T2940] vcpÿff8880ce2d1000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  357.728616] [ T2940] vcpÿff8880ce2d1000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  357.743762] [    C0] bit_putcs: width=1 cellsize=9 counth maxcnt‘0 scan_align=0 buf_align=0 image.widthT4 image.height=9 pitchh
[  357.743783] [    C0] =================================
[  357.743803] [    C0] BUG: KASAN: slab-out-of-bounds in bit_putcs+0x6a0/0x980
[  357.743822] [    C0] Read of size 1 at addr ffff8880d46ff343 by task a.out/2940
[  357.743830] [    C0]
[  357.743848] [    C0] CPU: 0 PID: 2940 Comm: a.out Not tainted 5.9.0-rc6+ #635
[  357.743871] [    C0] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[  357.743880] [    C0] Call Trace:
[  357.743891] [    C0]  dump_stack+0x161/0x1c3
[  357.743902] [    C0]  ? bit_putcs+0x6a0/0x980
[  357.743914] [    C0]  ? bit_putcs+0x6a0/0x980
[  357.743932] [    C0]  print_address_description.constprop.0.cold+0xd3/0x4c5
[  357.743944] [    C0]  ? log_store.cold+0x16/0x16
[  357.743956] [    C0]  ? vprintk_func+0xe2/0x155
[  357.743968] [    C0]  ? bit_putcs+0x6a0/0x980
[  357.743979] [    C0]  ? bit_putcs+0x6a0/0x980
[  357.743992] [    C0]  kasan_report.cold+0x1f/0x42
[  357.744003] [    C0]  ? bit_putcs+0x6a0/0x980
[  357.744014] [    C0]  bit_putcs+0x6a0/0x980
[  357.744026] [    C0]  ? bit_clear+0x2f0/0x2f0
[  357.744038] [    C0]  ? find_held_lock+0x85/0xa0
[  357.744052] [    C0]  ? raw_notifier_call_chain+0x31/0x40
[  357.744067] [    C0]  ? fb_get_color_depth.part.0+0x57/0xe0
[  357.744082] [    C0]  ? __sanitizer_cov_trace_switch+0x49/0x80
[  357.744093] [    C0]  fbcon_putcs+0x1d8/0x1e0
[  357.744105] [    C0]  ? bit_clear+0x2f0/0x2f0
[  357.744118] [    C0]  vt_console_print+0x72d/0x870
[  357.744130] [    C0]  ? fb_flashcursor+0x230/0x230
[  357.744144] [    C0]  ? screen_glyph_unicode+0x140/0x140
[  357.744157] [    C0]  ? rwlock_bug.part.0+0x50/0x50
[  357.744171] [    C0]  ? screen_glyph_unicode+0x140/0x140
[  357.744183] [    C0]  console_unlock+0x92c/0xb30
[  357.744195] [    C0]  vt_ioctl.cold+0x182/0x3a2
[  357.744210] [    C0]  ? complete_change_console+0x1e0/0x1e0
[  357.744222] [    C0]  ? find_held_lock+0x85/0xa0
[  357.744237] [    C0]  ? debug_check_no_obj_freed+0x18d/0x276
[  357.744249] [    C0]  ? lock_downgrade+0x3e0/0x3e0
[  357.744261] [    C0]  ? find_held_lock+0x85/0xa0
[  357.744274] [    C0]  ? lock_is_held_type+0xbf/0xf0
[  357.744285] [    C0]  ? putname+0xa7/0xc0
[  357.744296] [    C0]  ? putname+0xa7/0xc0
[  357.744306] [    C0]  ? putname+0xa7/0xc0
[  357.744322] [    C0]  ? __sanitizer_cov_trace_switch+0x49/0x80
[  357.744336] [    C0]  ? complete_change_console+0x1e0/0x1e0
[  357.744361] [    C0]  ? tty_ioctl+0x7c4/0xec0
[  357.744373] [    C0]  tty_ioctl+0x7c4/0xec0
[  357.744387] [    C0]  ? kmem_cache_free.part.0+0x1b0/0x1e0
[  357.744399] [    C0]  ? tty_vhangup+0x30/0x30
[  357.744414] [    C0]  ? __sanitizer_cov_trace_switch+0x49/0x80
[  357.744426] [    C0]  ? do_vfs_ioctl+0x224/0xc50
[  357.744439] [    C0]  ? ioctl_file_clone+0x140/0x140
[  357.744452] [    C0]  ? file_open_root+0x420/0x420
[  357.744467] [    C0]  ? check_preemption_disabled+0x50/0x130
[  357.744479] [    C0]  ? lock_is_held_type+0xbf/0xf0
[  357.744495] [    C0]  ? syscall_enter_from_user_mode+0x1c/0x60
[  357.744509] [    C0]  ? rcu_read_lock_sched_held+0xa0/0xd0
[  357.744521] [    C0]  ? mark_held_locks+0x24/0x90
[  357.744533] [    C0]  ? tty_vhangup+0x30/0x30
[  357.744545] [    C0]  __x64_sys_ioctl+0xec/0x140
[  357.744557] [    C0]  do_syscall_64+0x31/0x70
[  357.744572] [    C0]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  357.744583] [    C0] RIP: 0033:0x7f9b8316150b
[  357.744632] [    C0] Code: 0f 1e fa 48 8b 05 85 39 0d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 55 39 0d 00 f7 d8 64 89 01 48
[  357.744647] [    C0] RSP: 002b:00007ffe190139b8 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[  357.744680] [    C0] RAX: ffffffffffffffda RBX: 000055dc2ea7b220 RCX: 00007f9b8316150b
[  357.744701] [    C0] RDX: 00007ffe190139cc RSI: 000000000000560a RDI: 0000000000000003
[  357.744721] [    C0] RBP: 0000000000000003 R08: 0000000000000000 R09: 00007f9b83257d50
[  357.744741] [    C0] R10: 0000000000000000 R11: 0000000000000246 R12: 000055dc2ea7b130
[  357.744762] [    C0] R13: 00007ffe19013ad0 R14: 0000000000000000 R15: 0000000000000000
[  357.744769] [    C0]
[  357.744781] [    C0] Allocated by task 2940:
[  357.744793] [    C0]  kasan_save_stack+0x1f/0x40
[  357.744808] [    C0]  __kasan_kmalloc.constprop.0+0xbf/0xd0
[  357.744819] [    C0]  __kmalloc+0x57d/0x9d0
[  357.744831] [    C0]  fbcon_set_font+0x1a6/0x4a0
[  357.744843] [    C0]  con_font_op+0x8e2/0xac0
[  357.744854] [    C0]  vt_ioctl+0x1186/0x21a0
[  357.744866] [    C0]  tty_ioctl+0x7c4/0xec0
[  357.744878] [    C0]  __x64_sys_ioctl+0xec/0x140
[  357.744889] [    C0]  do_syscall_64+0x31/0x70
[  357.744905] [    C0]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  357.744912] [    C0]
[  357.744932] [    C0] The buggy address belongs to the object at ffff8880d46ff000
[  357.744949] [    C0]  which belongs to the cache kmalloc-1k of size 1024
[  357.744967] [    C0] The buggy address is located 835 bytes inside of
[  357.744985] [    C0]  1024-byte region [ffff8880d46ff000, ffff8880d46ff400)
[  357.745000] [    C0] The buggy address belongs to the page:
[  357.745027] [    C0] page:00000000878ccadc refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xd46ff
[  357.745040] [    C0] flags: 0xfffe0000000200(slab)
[  357.745063] [    C0] raw: 00fffe0000000200 ffffea00032a0808 ffffea00035ae308 ffff8880d6840700
[  357.745086] [    C0] raw: 0000000000000000 ffff8880d46ff000 0000000100000002 ffff8880cbe8b281
[  357.745103] [    C0] page dumped because: kasan: bad access detected
[  357.745117] [    C0] page->mem_cgroup:ffff8880cbe8b281
[  357.745125] [    C0]
[  357.745140] [    C0] Memory state around the buggy address:
[  357.745162] [    C0]  ffff8880d46ff200: 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  357.745186] [    C0]  ffff8880d46ff280: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  357.745208] [    C0] >ffff8880d46ff300: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  357.745224] [    C0]                                            ^
[  357.745246] [    C0]  ffff8880d46ff380: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  357.745267] [    C0]  ffff8880d46ff400: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  357.745288] [    C0] =================================
[  357.745305] [    C0] Disabling lock debugging due to kernel taint
[  357.745349] [    C0] bit_putcs: width=1 cellsize=9 countF maxcnt‘0 scan_align=0 buf_align=0 image.width68 image.height=9 pitchF
[  357.759878] [    C0] bit_putcs: width=1 cellsize=9 count€ maxcnt‘0 scan_align=0 buf_align=0 image.widthd0 image.height=9 pitch€
[  357.759910] [    C0] bit_putcs: width=1 cellsize=9 countt maxcnt‘0 scan_align=0 buf_align=0 image.widthY2 image.height=9 pitcht
[  357.775006] [    C0] bit_putcs: width=1 cellsize=9 count€ maxcnt‘0 scan_align=0 buf_align=0 image.widthd0 image.height=9 pitch€
----------

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: KASAN: use-after-free Read in bit_putcs
  2020-09-26 16:25   ` Tetsuo Handa
@ 2020-09-26 19:39     ` Peilin Ye
  2020-09-27  0:25     ` Tetsuo Handa
  1 sibling, 0 replies; 18+ messages in thread
From: Peilin Ye @ 2020-09-26 19:39 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: syzbot, linux-fbdev, b.zolnierkie, daniel.vetter, deller,
	syzkaller-bugs, linux-kernel, dri-devel, gregkh, jirislaby,
	yepeilin.cs

On Sun, Sep 27, 2020 at 01:25:17AM +0900, Tetsuo Handa wrote:
> A simplified reproducer and debug printk() patch shown below reported that
> vc_font.height is increased to 9 via ioctl(VT_RESIZEX) after it was once
> decreased from 16 to 2 via ioctl(PIO_FONT).
> 
> 
> 
> Since vc_resize() with v.v_rows = 0 preserves current vc->vc_rows value,
> this reproducer is bypassing
> 
> 	if (v.v_clin) {
> 		int rows = v.v_vlin / v.v_clin;
> 		if (v.v_rows != rows) {
> 			if (v.v_rows) /* Parameters don't add up */
> 				return -EINVAL;
> 			v.v_rows = rows;
> 		}
> 	}
> 
> check by setting v.v_vlin = 1 and v.v_clin = 9.
> 
> If v.v_vcol > 0 and v.v_vcol != vc->vc_cols (though this reproducer is passing
> v.v_vcol = 0), tty_do_resize() from vc_do_resize() from vc_resize() can make
> "struct tty_struct"->winsize.ws_ypixel = 1 despite
> "struct tty_struct"->winsize.vc->vc_rows = vc->vc_rows (which is usually larger
> than 1). Does such winsize (a row has 1 / vc->vc_rows pixel) make sense?
> 
> 
> 
> Since I don't know the meaning of "struct vt_consize"->v_clin (which is commented
> with "/* number of pixel rows per character */" but does it mean font size ?),
> I don't know why we can assign that value to vcp->vc_font.height via
> 
> 	if (v.v_clin)
> 		vcp->vc_font.height = v.v_clin;
> 
> in vt_resizex(). While ioctl(PIO_FONT) needs to pass vc->vc_sw->con_font_set()
> check in con_font_set(), ioctl(VT_RESIZEX) does not pass it in vt_resizex()...
> 
> Since this problem does not happen if I remove
> 
> 	if (v.v_clin)
> 		vcp->vc_font.height = v.v_clin;

Hi Tetsuo!

>  from vt_resizex(), I guess that some variables are getting confused by change
> of vc->vc_font.height ...

Yes, see bit_putcs():

(drivers/video/fbdev/core/bitblit.c)
static void bit_putcs(struct vc_data *vc, struct fb_info *info,
		      const unsigned short *s, int count, int yy, int xx,
		      int fg, int bg)
{
	struct fb_image image;
	u32 width = DIV_ROUND_UP(vc->vc_font.width, 8);
	u32 cellsize = width * vc->vc_font.height;
	    ^^^^^^^^		   ^^^^^^^^^^^^^^

`cellsize` is now too large. Later, in bit_putcs_aligned():

	while (cnt--) {
		src = vc->vc_font.data + (scr_readw(s++)&
					  charmask)*cellsize;
						    ^^^^^^^^

`src` goes out of bounds of the data buffer. At first glance I guess
this is an out-of-bound read reported as a use-after-free read? The
crashlog says:

[  149.732103][ T6693] Allocated by task 6667:
[ 149.732115][ T6693] kasan_save_stack (mm/kasan/common.c:48)
[ 149.732121][ T6693] __kasan_kmalloc.constprop.0 (mm/kasan/common.c:56 mm/kasan/common.c:461)
[ 149.732126][ T6693] __kmalloc (mm/slab.c:3656 mm/slab.c:3664)
[ 149.732133][ T6693] alloc_pipe_info (fs/pipe.c:810)
[ 149.732139][ T6693] create_pipe_files (fs/pipe.c:883 fs/pipe.c:914)
[ 149.732145][ T6693] do_pipe2 (fs/pipe.c:965 fs/pipe.c:1012)

I'm not sure, but I don't think a buffer allocated in fs/pipe.c is
related here. Maybe they just live near each other on the heap?

To resolve this out-of-bound issue for now, I think the easiest way
is to add a range check in bit_putcs(), or bit_putcs_aligned().

...but yeah, that `VT_RESIZEX` ioctl looks really buggy, and is already
causing more issues:

KASAN: global-out-of-bounds Read in fbcon_get_font
Link: https://syzkaller.appspot.com/bug?id\bb8be45afea11888776f897895aef9ad1c3ecfd

This was also caused by `VT_RESIZEX`...

Thank you,
Peilin Ye

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: KASAN: use-after-free Read in bit_putcs
  2020-09-26 16:25   ` Tetsuo Handa
  2020-09-26 19:39     ` Peilin Ye
@ 2020-09-27  0:25     ` Tetsuo Handa
  2020-09-27  8:28       ` Tetsuo Handa
  1 sibling, 1 reply; 18+ messages in thread
From: Tetsuo Handa @ 2020-09-27  0:25 UTC (permalink / raw)
  To: syzbot, b.zolnierkie, daniel.vetter, deller, gregkh, jirislaby,
	syzkaller-bugs, Linus Torvalds
  Cc: linux-fbdev, linux-kernel, dri-devel

On 2020/09/27 4:39, Peilin Ye wrote:
> On Sun, Sep 27, 2020 at 01:25:17AM +0900, Tetsuo Handa wrote:
>> Since I don't know the meaning of "struct vt_consize"->v_clin (which is commented
>> with "/* number of pixel rows per character */" but does it mean font size ?),
>> I don't know why we can assign that value to vcp->vc_font.height via
>>
>> 	if (v.v_clin)
>> 		vcp->vc_font.height = v.v_clin;
>>
>> in vt_resizex(). While ioctl(PIO_FONT) needs to pass vc->vc_sw->con_font_set()
>> check in con_font_set(), ioctl(VT_RESIZEX) does not pass it in vt_resizex()...
>>
>> Since this problem does not happen if I remove
>>
>> 	if (v.v_clin)
>> 		vcp->vc_font.height = v.v_clin;
> 
> Hi Tetsuo!
> 
>>  from vt_resizex(), I guess that some variables are getting confused by change
>> of vc->vc_font.height ...
> 
> Yes, see bit_putcs():
> 
> (drivers/video/fbdev/core/bitblit.c)
> static void bit_putcs(struct vc_data *vc, struct fb_info *info,
> 		      const unsigned short *s, int count, int yy, int xx,
> 		      int fg, int bg)
> {
> 	struct fb_image image;
> 	u32 width = DIV_ROUND_UP(vc->vc_font.width, 8);
> 	u32 cellsize = width * vc->vc_font.height;
> 	    ^^^^^^^^		   ^^^^^^^^^^^^^^
> 
> `cellsize` is now too large. Later, in bit_putcs_aligned():
> 
> 	while (cnt--) {
> 		src = vc->vc_font.data + (scr_readw(s++)&
> 					  charmask)*cellsize;
> 						    ^^^^^^^^
> 
> `src` goes out of bounds of the data buffer. At first glance I guess
> this is an out-of-bound read reported as a use-after-free read? The
> crashlog says:

How this OOB access is reported varies.

> 
> To resolve this out-of-bound issue for now, I think the easiest way
> is to add a range check in bit_putcs(), or bit_putcs_aligned().
> 
> ...but yeah, that `VT_RESIZEX` ioctl looks really buggy, and is already
> causing more issues:

At least, since not all fonts have height = 32 (e.g. font_vga_8x8 is height = 8),
allow changing vc->vc_font.height with only

	if (v.v_clin > 32)
		return -EINVAL;

validation in VT_RESIZEX looks wrong. This needs more validations.



By the way, can we find a user of VT_RESIZEX? As far as I googled with "VT_RESIZEX",
I couldn't find a userspace program; only explanation of VT_RESIZEX and kernel patches
related to VT_RESIZEX are found. Also, while console_ioctl(4) man page says

  Any parameter may be set to zero, indicating "no change"

, the assignment

	if (!v.v_vlin)
		v.v_vlin = vc->vc_scan_lines;

changes the meaning to

   If v_vlin parameter is set to zero, the value for associated console is copied
   to each console (instead of preserving current value for that console)

. Maybe for now we can try this (effectively making VT_RESIZEX = VT_RESIZE) ?

 vt_ioctl.c |   57 ++++++++++-----------------------------------------------
 1 file changed, 10 insertions(+), 47 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index a4e520bdd521..bc33938e2f20 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -773,58 +773,21 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
 	if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
 		return -EFAULT;
 
-	/* FIXME: Should check the copies properly */
-	if (!v.v_vlin)
-		v.v_vlin = vc->vc_scan_lines;
-
-	if (v.v_clin) {
-		int rows = v.v_vlin / v.v_clin;
-		if (v.v_rows != rows) {
-			if (v.v_rows) /* Parameters don't add up */
-				return -EINVAL;
-			v.v_rows = rows;
-		}
-	}
-
-	if (v.v_vcol && v.v_ccol) {
-		int cols = v.v_vcol / v.v_ccol;
-		if (v.v_cols != cols) {
-			if (v.v_cols)
-				return -EINVAL;
-			v.v_cols = cols;
-		}
-	}
-
-	if (v.v_clin > 32)
-		return -EINVAL;
+	if (v.v_vlin)
+		pr_info_once("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n");
+	if (v.v_clin)
+		pr_info_once("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n");
 
+	console_lock();
 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
-		struct vc_data *vcp;
+		vc = vc_cons[i].d;
 
-		if (!vc_cons[i].d)
-			continue;
-		console_lock();
-		vcp = vc_cons[i].d;
-		if (vcp) {
-			int ret;
-			int save_scan_lines = vcp->vc_scan_lines;
-			int save_font_height = vcp->vc_font.height;
-
-			if (v.v_vlin)
-				vcp->vc_scan_lines = v.v_vlin;
-			if (v.v_clin)
-				vcp->vc_font.height = v.v_clin;
-			vcp->vc_resize_user = 1;
-			ret = vc_resize(vcp, v.v_cols, v.v_rows);
-			if (ret) {
-				vcp->vc_scan_lines = save_scan_lines;
-				vcp->vc_font.height = save_font_height;
-				console_unlock();
-				return ret;
-			}
+		if (vc) {
+			vc->vc_resize_user = 1;
+			vc_resize(vc, v.v_cols, v.v_rows);
 		}
-		console_unlock();
 	}
+	console_unlock();
 
 	return 0;
 }

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: KASAN: use-after-free Read in bit_putcs
  2020-09-27  0:25     ` Tetsuo Handa
@ 2020-09-27  8:28       ` Tetsuo Handa
  2020-09-27  9:27         ` Peilin Ye
  0 siblings, 1 reply; 18+ messages in thread
From: Tetsuo Handa @ 2020-09-27  8:28 UTC (permalink / raw)
  To: syzbot, b.zolnierkie, daniel.vetter, deller, gregkh, jirislaby,
	syzkaller-bugs, Linus Torvalds, Peilin Ye
  Cc: linux-fbdev, linux-kernel, dri-devel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 11531 bytes --]

Well, vt_io_ioctl(PIO_FONT) initializes "struct console_font_op op;" with

  op.width = 8;
  op.height = 0;
  op.charcount = 256;

and calls con_font_set() from con_font_op(). But the "/* Need to guess font height [compat] */"
chunk in con_font_set() guesses font's height due to being initialized with op.height = 0.
Then, con_font_set() calls fbcon_set_font() via vc->vc_sw->con_font_set(), and fbcon_set_font()
allocates minimal amount of memory for font data based on font's height calcllated by con_font_set().

Therefore, any attempt to change font's height (like vt_resizex()) larger than font's height
calculated by con_font_set() can cause OOB read of memory block for font data. If we allocate
maximal amount of memory for any font, OOB read of memory block for font data should not happen.

----------------------------------------

static char fontdata[8192] = { 2 };

[  227.065369] bit_putcs: width=1 cellsize=1 count€ maxcnt92 scan_align=0 buf_align=0 image.height=1
[  227.066254] bit_putcs: width=1 cellsize=1 count€ maxcnt92 scan_align=0 buf_align=0 image.height=1
[  227.067642] vcÿff8880d69b4000 v.v_rows=0 v.v_cols=0 v.v_vlin=1 v.v_clin=9 v.v_vcol=0 v.v_ccol=0 ret=0
[  227.067699] vcpÿff8880d69b4000 before: ->vc_rowsH0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height=1
[  227.067774] vcpÿff8880d69b4000 after: ->vc_rowsH0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height=1 ret=0
[  227.067831] vcpÿff8880cac4b000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  227.067891] vcpÿff8880cac4b000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  227.067947] vcpÿff8880c6180000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  227.068007] vcpÿff8880c6180000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  227.068063] vcpÿff8880d6b84000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  227.068123] vcpÿff8880d6b84000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  227.068179] vcpÿff8880ca8c0000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  227.068255] vcpÿff8880ca8c0000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  227.068455] vcpÿff8880cbd5d000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  227.068515] vcpÿff8880cbd5d000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  227.084709] =================================
[  227.084729] BUG: KASAN: slab-out-of-bounds in soft_cursor+0x34e/0x4a0
[  227.084748] Read of size 9 at addr ffff8880c98d5930 by task a.out/1662

[  227.084786] CPU: 3 PID: 1662 Comm: a.out Not tainted 5.9.0-rc6+ #639
[  227.084810] Hardware name: innotek GmbH VirtualBox/VirtualBox, BIOS VirtualBox 12/01/2006
[  227.084818] Call Trace:
[  227.084830]  dump_stack+0x161/0x1c3
[  227.084842]  ? soft_cursor+0x34e/0x4a0
[  227.084854]  ? soft_cursor+0x34e/0x4a0
[  227.084871]  print_address_description.constprop.0.cold+0xd3/0x4c5
[  227.084884]  ? lock_is_held_type+0xbf/0xf0
[  227.084896]  ? vprintk_func+0xe2/0x155
[  227.084908]  ? soft_cursor+0x34e/0x4a0
[  227.084920]  ? soft_cursor+0x34e/0x4a0
[  227.084932]  kasan_report.cold+0x1f/0x42
[  227.084944]  ? soft_cursor+0x34e/0x4a0
[  227.084957]  check_memory_region+0x152/0x1b0
[  227.084967]  memcpy+0x24/0x60
[  227.084979]  soft_cursor+0x34e/0x4a0
[  227.084990]  bit_cursor+0x7f6/0xce6
[  227.085001]  ? bit_putcs+0x320/0x320
[  227.085016]  ? fb_get_color_depth.part.0+0x57/0xe0
[  227.085031]  ? __sanitizer_cov_trace_switch+0x49/0x80
[  227.085042]  ? bit_putcs+0x320/0x320
[  227.085054]  fbcon_cursor+0x241/0x2c0
[  227.085065]  hide_cursor+0x58/0x150
[  227.085077]  vt_console_print+0x865/0x870
[  227.085089]  ? lock_release+0x480/0x480
[  227.085102]  ? lock_downgrade+0x3e0/0x3e0
[  227.085115]  ? do_raw_spin_lock+0x110/0x1f0
[  227.085128]  ? screen_glyph_unicode+0x140/0x140
[  227.085141]  ? rwlock_bug.part.0+0x50/0x50
[  227.085156]  ? check_preemption_disabled+0x50/0x130
[  227.085169]  ? screen_glyph_unicode+0x140/0x140
[  227.085181]  console_unlock+0x92c/0xb30
[  227.085193]  vt_ioctl.cold+0x182/0x3a2
[  227.085207]  ? complete_change_console+0x1e0/0x1e0
[  227.085219]  ? find_held_lock+0x85/0xa0
[  227.085234]  ? debug_check_no_obj_freed+0x18d/0x276
[  227.085246]  ? lock_downgrade+0x3e0/0x3e0
[  227.085258]  ? find_held_lock+0x85/0xa0
[  227.085271]  ? lock_is_held_type+0xbf/0xf0
[  227.085281]  ? putname+0xa7/0xc0
[  227.085292]  ? putname+0xa7/0xc0
[  227.085302]  ? putname+0xa7/0xc0
[  227.085317]  ? __sanitizer_cov_trace_switch+0x49/0x80
[  227.085332]  ? complete_change_console+0x1e0/0x1e0
[  227.085343]  ? tty_ioctl+0x7c4/0xec0
[  227.085368]  tty_ioctl+0x7c4/0xec0
[  227.085383]  ? kmem_cache_free.part.0+0x1b0/0x1e0
[  227.085394]  ? tty_vhangup+0x30/0x30
[  227.085409]  ? __sanitizer_cov_trace_switch+0x49/0x80
[  227.085421]  ? do_vfs_ioctl+0x224/0xc50
[  227.085434]  ? ioctl_file_clone+0x140/0x140
[  227.085449]  ? rcu_read_lock_sched_held+0xa0/0xd0
[  227.085464]  ? rcu_read_lock_any_held.part.0+0x30/0x30
[  227.085479]  ? check_preemption_disabled+0x50/0x130
[  227.085491]  ? lock_is_held_type+0xbf/0xf0
[  227.085506]  ? syscall_enter_from_user_mode+0x1c/0x60
[  227.085520]  ? rcu_read_lock_sched_held+0xa0/0xd0
[  227.085533]  ? mark_held_locks+0x24/0x90
[  227.085544]  ? tty_vhangup+0x30/0x30
[  227.085556]  __x64_sys_ioctl+0xec/0x140
[  227.085568]  do_syscall_64+0x31/0x70
[  227.085583]  entry_SYSCALL_64_after_hwframe+0x44/0xa9
[  227.085594] RIP: 0033:0x7f261b69e50b
[  227.085643] Code: 0f 1e fa 48 8b 05 85 39 0d 00 64 c7 00 26 00 00 00 48 c7 c0 ff ff ff ff c3 66 0f 1f 44 00 00 f3 0f 1e fa b8 10 00 00 00 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 8b 0d 55 39 0d 00 f7 d8 64 89 01 48
[  227.085658] RSP: 002b:00007fff1894fb98 EFLAGS: 00000246 ORIG_RAX: 0000000000000010
[  227.085691] RAX: ffffffffffffffda RBX: 0000560076c54220 RCX: 00007f261b69e50b
[  227.085711] RDX: 00007fff1894fbac RSI: 000000000000560a RDI: 0000000000000003
[  227.085731] RBP: 0000000000000003 R08: 0000000000000000 R09: 00007f261b794d50
[  227.085751] R10: 0000000000000000 R11: 0000000000000246 R12: 0000560076c54130
[  227.085771] R13: 00007fff1894fcb0 R14: 0000000000000000 R15: 0000000000000000

[  227.085791] Allocated by task 1662:
[  227.085803]  kasan_save_stack+0x1f/0x40
[  227.085817]  __kasan_kmalloc.constprop.0+0xbf/0xd0
[  227.085828]  __kmalloc+0x57d/0x9d0
[  227.085840]  fbcon_set_font+0x1a6/0x4a0
[  227.085852]  con_font_op+0x8e2/0xac0
[  227.085863]  vt_ioctl+0x1186/0x21a0
[  227.085874]  tty_ioctl+0x7c4/0xec0
[  227.085886]  __x64_sys_ioctl+0xec/0x140
[  227.085898]  do_syscall_64+0x31/0x70
[  227.085913]  entry_SYSCALL_64_after_hwframe+0x44/0xa9

[  227.085940] The buggy address belongs to the object at ffff8880c98d5800
[  227.085957]  which belongs to the cache kmalloc-512 of size 512
[  227.085974] The buggy address is located 304 bytes inside of
[  227.085992]  512-byte region [ffff8880c98d5800, ffff8880c98d5a00)
[  227.086007] The buggy address belongs to the page:
[  227.086033] page:00000000022668f3 refcount:1 mapcount:0 mapping:0000000000000000 index:0x0 pfn:0xc98d5
[  227.086047] flags: 0xfffe0000000200(slab)
[  227.086081] raw: 00fffe0000000200 ffffea00032c4b08 ffffea0003205748 ffff8880d6840600
[  227.086104] raw: 0000000000000000 ffff8880c98d5000 0000000100000004 ffff8880d2419241
[  227.086121] page dumped because: kasan: bad access detected
[  227.086136] page->mem_cgroup:ffff8880d2419241

[  227.086158] Memory state around the buggy address:
[  227.086179]  ffff8880c98d5800: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  227.086201]  ffff8880c98d5880: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
[  227.086222] >ffff8880c98d5900: 00 00 fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  227.086237]                                      ^
[  227.086258]  ffff8880c98d5980: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  227.086279]  ffff8880c98d5a00: fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc fc
[  227.086301] =================================

----------------------------------------

static char fontdata[8192] = { 2, 3 };

[  464.415205] vcpÿff8880d69b4000 before: ->vc_rows$0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=1 ->vc_font.height=9 save_font_height=2
[  464.415265] vcpÿff8880d69b4000 after: ->vc_rows$0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=1 ->vc_font.height=9 save_font_height=2 ret=0

[  464.431257] bit_putcs: width=1 cellsize=9 counth maxcnt‘0 scan_align=0 buf_align=0 image.height=9
[  464.431279] =================================
[  464.431299] BUG: KASAN: slab-out-of-bounds in bit_putcs.cold+0x570/0x5aa
[  464.431319] Read of size 1 at addr ffff8880ca0ccb43 by task a.out/1757

----------------------------------------

static char fontdata[8192] = "0123456789abcdef0123456789abcdef";

[  300.610119] bit_putcs: width=1 cellsize2 count€ maxcnt%6 scan_align=0 buf_align=0 image.height2
[  300.630932] bit_putcs: width=1 cellsize2 count€ maxcnt%6 scan_align=0 buf_align=0 image.height2
[  300.652194] vcÿff8880d69b4000 v.v_rows=0 v.v_cols=0 v.v_vlin=1 v.v_clin=9 v.v_vcol=0 v.v_ccol=0 ret=0
[  300.652249] vcpÿff8880d69b4000 before: ->vc_rows\x15 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height2
[  300.652308] vcpÿff8880d69b4000 after: ->vc_rows\x15 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height2 ret=0
[  300.652500] vcpÿff8880d55ba000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  300.652559] vcpÿff8880d55ba000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  300.652613] vcpÿff8880d4d87000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  300.652690] vcpÿff8880d4d87000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  300.652767] vcpÿff8880d546b000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  300.652849] vcpÿff8880d546b000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  300.652926] vcpÿff8880c8f85000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  300.653008] vcpÿff8880c8f85000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  300.653085] vcpÿff8880d55db000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
[  300.653167] vcpÿff8880d55db000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
[  300.665421] bit_putcs: width=1 cellsize=9 counth maxcnt‘0 scan_align=0 buf_align=0 image.height=9
[  300.665450] bit_putcs: width=1 cellsize=9 countF maxcnt‘0 scan_align=0 buf_align=0 image.height=9

----------------------------------------

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: KASAN: use-after-free Read in bit_putcs
  2020-09-27  8:28       ` Tetsuo Handa
@ 2020-09-27  9:27         ` Peilin Ye
  2020-09-27 11:46           ` [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE Tetsuo Handa
  0 siblings, 1 reply; 18+ messages in thread
From: Peilin Ye @ 2020-09-27  9:27 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: syzbot, linux-fbdev, b.zolnierkie, daniel.vetter, deller,
	syzkaller-bugs, linux-kernel, dri-devel, Linus Torvalds, gregkh,
	jirislaby, Peilin Ye

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="windows-1254", Size: 3518 bytes --]

On Sun, Sep 27, 2020 at 05:28:12PM +0900, Tetsuo Handa wrote:
> Well, vt_io_ioctl(PIO_FONT) initializes "struct console_font_op op;" with
> 
>   op.width = 8;
>   op.height = 0;
>   op.charcount = 256;
> 
> and calls con_font_set() from con_font_op(). But the "/* Need to guess font height [compat] */"
> chunk in con_font_set() guesses font's height due to being initialized with op.height = 0.
> Then, con_font_set() calls fbcon_set_font() via vc->vc_sw->con_font_set(), and fbcon_set_font()
> allocates minimal amount of memory for font data based on font's height calcllated by con_font_set().
> 
> Therefore, any attempt to change font's height (like vt_resizex()) larger than font's height
> calculated by con_font_set() can cause OOB read of memory block for font data. If we allocate
> maximal amount of memory for any font, OOB read of memory block for font data should not happen.
> 
> ----------------------------------------
> 
> static char fontdata[8192] = { 2 };
> 
> [  227.065369] bit_putcs: width=1 cellsize=1 count€ maxcnt92 scan_align=0 buf_align=0 image.height=1
> [  227.066254] bit_putcs: width=1 cellsize=1 count€ maxcnt92 scan_align=0 buf_align=0 image.height=1
> [  227.067642] vcÿff8880d69b4000 v.v_rows=0 v.v_cols=0 v.v_vlin=1 v.v_clin=9 v.v_vcol=0 v.v_ccol=0 ret=0
> [  227.067699] vcpÿff8880d69b4000 before: ->vc_rowsH0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height=1
> [  227.067774] vcpÿff8880d69b4000 after: ->vc_rowsH0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines@0 ->vc_font.height=9 save_font_height=1 ret=0
> [  227.067831] vcpÿff8880cac4b000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
> [  227.067891] vcpÿff8880cac4b000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
> [  227.067947] vcpÿff8880c6180000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
> [  227.068007] vcpÿff8880c6180000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
> [  227.068063] vcpÿff8880d6b84000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
> [  227.068123] vcpÿff8880d6b84000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
> [  227.068179] vcpÿff8880ca8c0000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
> [  227.068255] vcpÿff8880ca8c0000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
> [  227.068455] vcpÿff8880cbd5d000 before: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16
> [  227.068515] vcpÿff8880cbd5d000 after: ->vc_rows0 ->vc_cols€ ->vc_scan_lines=1 save_scan_lines=0 ->vc_font.height=9 save_font_height\x16 ret=0
> [  227.084709] =================================
> [  227.084729] BUG: KASAN: slab-out-of-bounds in soft_cursor+0x34e/0x4a0
> [  227.084748] Read of size 9 at addr ffff8880c98d5930 by task a.out/1662

Very interesting, I remember seeing this on the syzbot dashboard...

Yes, I guess it is this one:
	KASAN: slab-out-of-bounds Read in soft_cursor
	https://syzkaller.appspot.com/bug?idk8355d27b2b94fb5cedf4655e3a59162d9e48e3

There is a `0x560aul` ioctl() in the reproducer, which is `VT_RESIZEX`.

Thank you,
Peilin Ye

^ permalink raw reply	[flat|nested] 18+ messages in thread

* [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-27  9:27         ` Peilin Ye
@ 2020-09-27 11:46           ` Tetsuo Handa
  2020-09-27 12:06             ` Greg KH
  2020-09-28 17:59             ` Martin Hostettler
  0 siblings, 2 replies; 18+ messages in thread
From: Tetsuo Handa @ 2020-09-27 11:46 UTC (permalink / raw)
  To: gregkh, jirislaby
  Cc: syzbot, linux-fbdev, b.zolnierkie, daniel.vetter, deller,
	syzkaller-bugs, linux-kernel, dri-devel, George Kennedy,
	Linus Torvalds, Peilin Ye

syzbot is reporting UAF/OOB read at bit_putcs()/soft_cursor() [1][2], for
vt_resizex() from ioctl(VT_RESIZEX) allows setting font height larger than
actual font height calculated by con_font_set() from ioctl(PIO_FONT).
Since fbcon_set_font() from con_font_set() allocates minimal amount of
memory based on actual font height calculated by con_font_set(),
use of vt_resizex() can cause UAF/OOB read for font data.

VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.

  #define VT_RESIZE   0x5609 /* set kernel's idea of screensize */
  #define VT_RESIZEX  0x560A /* set kernel's idea of screensize + more */

So far we are not aware of syzbot reports caused by setting non-zero value
to v_vlin parameter. But given that it is possible that nobody is using
VT_RESIZEX, we can try removing support for v_clin and v_vlin parameters.

Therefore, this patch effectively makes VT_RESIZEX behave like VT_RESIZE,
with emitting a message if somebody is still using v_clin and/or v_vlin
parameters.

[1] https://syzkaller.appspot.com/bug?id2577e96d88447ded2d3b76d71254fb855245837
[2] https://syzkaller.appspot.com/bug?idk8355d27b2b94fb5cedf4655e3a59162d9e48e3

Reported-by: syzbot <syzbot+b308f5fd049fbbc6e74f@syzkaller.appspotmail.com>
Reported-by: syzbot <syzbot+16469b5e8e5a72e9131e@syzkaller.appspotmail.com>
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
---
 drivers/tty/vt/vt_ioctl.c | 57 +++++++--------------------------------
 1 file changed, 10 insertions(+), 47 deletions(-)

diff --git a/drivers/tty/vt/vt_ioctl.c b/drivers/tty/vt/vt_ioctl.c
index a4e520bdd521..bc33938e2f20 100644
--- a/drivers/tty/vt/vt_ioctl.c
+++ b/drivers/tty/vt/vt_ioctl.c
@@ -773,58 +773,21 @@ static int vt_resizex(struct vc_data *vc, struct vt_consize __user *cs)
 	if (copy_from_user(&v, cs, sizeof(struct vt_consize)))
 		return -EFAULT;
 
-	/* FIXME: Should check the copies properly */
-	if (!v.v_vlin)
-		v.v_vlin = vc->vc_scan_lines;
-
-	if (v.v_clin) {
-		int rows = v.v_vlin / v.v_clin;
-		if (v.v_rows != rows) {
-			if (v.v_rows) /* Parameters don't add up */
-				return -EINVAL;
-			v.v_rows = rows;
-		}
-	}
-
-	if (v.v_vcol && v.v_ccol) {
-		int cols = v.v_vcol / v.v_ccol;
-		if (v.v_cols != cols) {
-			if (v.v_cols)
-				return -EINVAL;
-			v.v_cols = cols;
-		}
-	}
-
-	if (v.v_clin > 32)
-		return -EINVAL;
+	if (v.v_vlin)
+		pr_info_once("\"struct vt_consize\"->v_vlin is ignored. Please report if you need this.\n");
+	if (v.v_clin)
+		pr_info_once("\"struct vt_consize\"->v_clin is ignored. Please report if you need this.\n");
 
+	console_lock();
 	for (i = 0; i < MAX_NR_CONSOLES; i++) {
-		struct vc_data *vcp;
+		vc = vc_cons[i].d;
 
-		if (!vc_cons[i].d)
-			continue;
-		console_lock();
-		vcp = vc_cons[i].d;
-		if (vcp) {
-			int ret;
-			int save_scan_lines = vcp->vc_scan_lines;
-			int save_font_height = vcp->vc_font.height;
-
-			if (v.v_vlin)
-				vcp->vc_scan_lines = v.v_vlin;
-			if (v.v_clin)
-				vcp->vc_font.height = v.v_clin;
-			vcp->vc_resize_user = 1;
-			ret = vc_resize(vcp, v.v_cols, v.v_rows);
-			if (ret) {
-				vcp->vc_scan_lines = save_scan_lines;
-				vcp->vc_font.height = save_font_height;
-				console_unlock();
-				return ret;
-			}
+		if (vc) {
+			vc->vc_resize_user = 1;
+			vc_resize(vc, v.v_cols, v.v_rows);
 		}
-		console_unlock();
 	}
+	console_unlock();
 
 	return 0;
 }
-- 
2.25.1

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-27 11:46           ` [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE Tetsuo Handa
@ 2020-09-27 12:06             ` Greg KH
  2020-09-28 17:59             ` Martin Hostettler
  1 sibling, 0 replies; 18+ messages in thread
From: Greg KH @ 2020-09-27 12:06 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: syzbot, linux-fbdev, George Kennedy, b.zolnierkie, daniel.vetter,
	deller, syzkaller-bugs, linux-kernel, dri-devel, Linus Torvalds,
	jirislaby, Peilin Ye

On Sun, Sep 27, 2020 at 08:46:30PM +0900, Tetsuo Handa wrote:
> syzbot is reporting UAF/OOB read at bit_putcs()/soft_cursor() [1][2], for
> vt_resizex() from ioctl(VT_RESIZEX) allows setting font height larger than
> actual font height calculated by con_font_set() from ioctl(PIO_FONT).
> Since fbcon_set_font() from con_font_set() allocates minimal amount of
> memory based on actual font height calculated by con_font_set(),
> use of vt_resizex() can cause UAF/OOB read for font data.
> 
> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
> 
>   #define VT_RESIZE   0x5609 /* set kernel's idea of screensize */
>   #define VT_RESIZEX  0x560A /* set kernel's idea of screensize + more */
> 
> So far we are not aware of syzbot reports caused by setting non-zero value
> to v_vlin parameter. But given that it is possible that nobody is using
> VT_RESIZEX, we can try removing support for v_clin and v_vlin parameters.

Debian code search doesn't show any users, and that's usually a good
indication of what userspace ioctls for old things like this, are being
used for.

So this makes sense to me, I'll queue it up, thanks!

greg k-h

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-27 11:46           ` [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE Tetsuo Handa
  2020-09-27 12:06             ` Greg KH
@ 2020-09-28 17:59             ` Martin Hostettler
  2020-09-29  1:12               ` Tetsuo Handa
  1 sibling, 1 reply; 18+ messages in thread
From: Martin Hostettler @ 2020-09-28 17:59 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: syzbot, linux-fbdev, George Kennedy, b.zolnierkie, daniel.vetter,
	deller, syzkaller-bugs, linux-kernel, dri-devel, Linus Torvalds,
	gregkh, jirislaby, Peilin Ye

On Sun, Sep 27, 2020 at 08:46:30PM +0900, Tetsuo Handa wrote:
> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
> 

It seems this is/was used by "svgatextmode" which seems to be at
http://www.ibiblio.org/pub/Linux/utils/console/

Not sure if that kind of software still has a chance to work nowadays.

 - Martin Hostettler

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-28 17:59             ` Martin Hostettler
@ 2020-09-29  1:12               ` Tetsuo Handa
  2020-09-29 10:52                 ` Martin Hostettler
  0 siblings, 1 reply; 18+ messages in thread
From: Tetsuo Handa @ 2020-09-29  1:12 UTC (permalink / raw)
  To: Martin Hostettler
  Cc: syzbot, linux-fbdev, George Kennedy, b.zolnierkie, daniel.vetter,
	deller, syzkaller-bugs, linux-kernel, dri-devel, Linus Torvalds,
	gregkh, jirislaby, Peilin Ye

On 2020/09/29 2:59, Martin Hostettler wrote:
> On Sun, Sep 27, 2020 at 08:46:30PM +0900, Tetsuo Handa wrote:
>> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
>> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
>>
> 
> It seems this is/was used by "svgatextmode" which seems to be at
> http://www.ibiblio.org/pub/Linux/utils/console/
> 
> Not sure if that kind of software still has a chance to work nowadays.
> 

Thanks for the information.

It seems that v.v_vlin = curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1)
and v.v_clin = curr_textmode->FontHeight . Thus, v.v_clin is font's height and seems to be non-zero.
But according to https://bugs.gentoo.org/19485 , people are using kernel framebuffer instead.

---------- SVGATextMode-1.10/SVGATextMode.c ----------

      /*
       * Resize the screen. Still needs LOTS more error checking to avoid dropping out in the middle, leaving
       * the user with a garbled screen.
       *
       * sresize will be TRUE when resizing tty's should be forced (due to the 2nd attempt do_VT_RESIZE will do
       * when not enough memory is free).
       *
       */

        /*
         * ALWAYS do a VT_RESIZE, even if we already did a VT_RESIZEX on a 1.3.3 or higher kernel,
         * until those kernel programmers make this unambiguous
         */

       if (do_VT_RESIZE(curr_textmode->cols, curr_textmode->rows, resize1x1)) sresize=TRUE;

       if (check_kernel_version(1,3,3, "VT_RESIZEX"))
         {
           /*
            * VDisplay must de divided by 2 for DoubleScan modes,
            * or VT_RESIZEX will fail -- until someone fixes the kernel
            * so it understands about doublescan modes.
            */
           if (do_VT_RESIZEX(curr_textmode->cols,
                             curr_textmode->rows,
                             curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1),
                             curr_textmode->FontHeight,
                             curr_textmode->HDisplay/8*curr_textmode->FontWidth,
                             curr_textmode->FontWidth, resize1x1)) sresize=TRUE;
         }

---------- SVGATextMode-1.10/ttyresize.c ----------

/*
 * if VT_RESIZEX not supported (i.e. when compiling on < 1.3.3 kernels), define it.
 * this is just te keep the compiler happy
 */

#ifndef VT_RESIZEX
#  define VT_RESIZEX  0x560A
   typedef struct vt_consize {
      ushort v_rows; ushort v_cols; ushort v_vlin; ushort v_clin; ushort v_vcol; ushort v_ccol;
    } vt_consize;
#endif


int do_VT_RESIZEX(int cols, int rows, int vlin, int clin, int vcol, int ccol, int allow1x1)
{
  struct vt_consize my_vt_size;      /* passes the new screen size on to the kernel */
  struct vt_consize dummy_vt_size = { 1 , 1 , 1 , 1 , 1 , 1 };
  int ram_needed = cols * rows * 2 * MAX_NR_CONSOLES;

  my_vt_size.v_rows = rows;
  my_vt_size.v_cols = cols;
  my_vt_size.v_vlin = vlin;
  my_vt_size.v_clin = clin;
  my_vt_size.v_vcol = vcol;
  my_vt_size.v_ccol = ccol;

  PDEBUG(("VT_RESIZEX(cols=%d,rows=%d,vlin=%d,clin=%d,vcol=%d,ccol=%d)\n",cols, rows, vlin, clin, vcol, ccol));

  return(generic_VT_RESIZE(&my_vt_size, &dummy_vt_size, allow1x1, ram_needed, VT_RESIZEX, "VT_RESIZEX"));
}

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-29  1:12               ` Tetsuo Handa
@ 2020-09-29 10:52                 ` Martin Hostettler
  2020-09-29 16:56                   ` Daniel Vetter
  0 siblings, 1 reply; 18+ messages in thread
From: Martin Hostettler @ 2020-09-29 10:52 UTC (permalink / raw)
  To: Tetsuo Handa
  Cc: syzbot, linux-fbdev, George Kennedy, b.zolnierkie, gregkh,
	deller, syzkaller-bugs, linux-kernel, dri-devel,
	Martin Hostettler, Linus Torvalds, daniel.vetter, jirislaby,
	Peilin Ye

On Tue, Sep 29, 2020 at 10:12:46AM +0900, Tetsuo Handa wrote:
> On 2020/09/29 2:59, Martin Hostettler wrote:
> > On Sun, Sep 27, 2020 at 08:46:30PM +0900, Tetsuo Handa wrote:
> >> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
> >> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
> >>
> > 
> > It seems this is/was used by "svgatextmode" which seems to be at
> > http://www.ibiblio.org/pub/Linux/utils/console/
> > 
> > Not sure if that kind of software still has a chance to work nowadays.
> > 
> 
> Thanks for the information.
> 
> It seems that v.v_vlin = curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1)
> and v.v_clin = curr_textmode->FontHeight . Thus, v.v_clin is font's height and seems to be non-zero.
> But according to https://bugs.gentoo.org/19485 , people are using kernel framebuffer instead.
> 

Yes, this seems to be from pre framebuffer times.

Back in the days "svga" was the wording you got for "pokes svga card
hardware registers from userspace drivers". And textmode means font
rendering is done via (fixed function in those times) hardware scanout
engine. Of course having only to update 2 bytes per character was a huge
saving early on. Likely this is also before vesa VBE was reliable.

So i guess the point where this all starts going wrong allowing the X parts
of the api to be combined with FB based rendering at all? Sounds the only
user didn't use that combination and so it was never tested?

Then again, this all relates to hardware from 20 years ago...

 - Martin Hostettler

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-29 10:52                 ` Martin Hostettler
@ 2020-09-29 16:56                   ` Daniel Vetter
  2020-09-29 17:10                     ` Greg KH
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel Vetter @ 2020-09-29 16:56 UTC (permalink / raw)
  To: Martin Hostettler
  Cc: syzbot, linux-fbdev, George Kennedy, b.zolnierkie, Tetsuo Handa,
	gregkh, deller, syzkaller-bugs, linux-kernel, dri-devel,
	Linus Torvalds, daniel.vetter, jirislaby, Peilin Ye

On Tue, Sep 29, 2020 at 12:52:03PM +0200, Martin Hostettler wrote:
> On Tue, Sep 29, 2020 at 10:12:46AM +0900, Tetsuo Handa wrote:
> > On 2020/09/29 2:59, Martin Hostettler wrote:
> > > On Sun, Sep 27, 2020 at 08:46:30PM +0900, Tetsuo Handa wrote:
> > >> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
> > >> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
> > >>
> > > 
> > > It seems this is/was used by "svgatextmode" which seems to be at
> > > http://www.ibiblio.org/pub/Linux/utils/console/
> > > 
> > > Not sure if that kind of software still has a chance to work nowadays.
> > > 
> > 
> > Thanks for the information.
> > 
> > It seems that v.v_vlin = curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1)
> > and v.v_clin = curr_textmode->FontHeight . Thus, v.v_clin is font's height and seems to be non-zero.
> > But according to https://bugs.gentoo.org/19485 , people are using kernel framebuffer instead.
> > 
> 
> Yes, this seems to be from pre framebuffer times.
> 
> Back in the days "svga" was the wording you got for "pokes svga card
> hardware registers from userspace drivers". And textmode means font
> rendering is done via (fixed function in those times) hardware scanout
> engine. Of course having only to update 2 bytes per character was a huge
> saving early on. Likely this is also before vesa VBE was reliable.
> 
> So i guess the point where this all starts going wrong allowing the X parts
> of the api to be combined with FB based rendering at all? Sounds the only
> user didn't use that combination and so it was never tested?
> 
> Then again, this all relates to hardware from 20 years ago...

Imo userspace modesetting should be burned down anywhere we can. We've
gotten away with this in drivers/gpu by just seamlessly transitioning to
kernel drivers.

Since th only userspace we've found seems to be able to cope if this ioctl
doesn't do anything, my vote goes towards ripping it out completely and
doing nothing in there. Only question is whether we should error or fail
with a silent success: Former is safer, latter can avoid a few regression
reports since the userspace tools keep "working", and usually people don't
notice for stuff this old. It worked in drivers/gpu :-)

Cheers, Daniel
-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-29 16:56                   ` Daniel Vetter
@ 2020-09-29 17:10                     ` Greg KH
  2021-04-11 21:43                       ` Maciej W. Rozycki
  0 siblings, 1 reply; 18+ messages in thread
From: Greg KH @ 2020-09-29 17:10 UTC (permalink / raw)
  To: Martin Hostettler, Tetsuo Handa, jirislaby, Peilin Ye, syzbot,
	b.zolnierkie, deller, syzkaller-bugs, Linus Torvalds, dri-devel,
	linux-fbdev, linux-kernel, George Kennedy

On Tue, Sep 29, 2020 at 06:56:57PM +0200, Daniel Vetter wrote:
> On Tue, Sep 29, 2020 at 12:52:03PM +0200, Martin Hostettler wrote:
> > On Tue, Sep 29, 2020 at 10:12:46AM +0900, Tetsuo Handa wrote:
> > > On 2020/09/29 2:59, Martin Hostettler wrote:
> > > > On Sun, Sep 27, 2020 at 08:46:30PM +0900, Tetsuo Handa wrote:
> > > >> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
> > > >> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
> > > >>
> > > > 
> > > > It seems this is/was used by "svgatextmode" which seems to be at
> > > > http://www.ibiblio.org/pub/Linux/utils/console/
> > > > 
> > > > Not sure if that kind of software still has a chance to work nowadays.
> > > > 
> > > 
> > > Thanks for the information.
> > > 
> > > It seems that v.v_vlin = curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1)
> > > and v.v_clin = curr_textmode->FontHeight . Thus, v.v_clin is font's height and seems to be non-zero.
> > > But according to https://bugs.gentoo.org/19485 , people are using kernel framebuffer instead.
> > > 
> > 
> > Yes, this seems to be from pre framebuffer times.
> > 
> > Back in the days "svga" was the wording you got for "pokes svga card
> > hardware registers from userspace drivers". And textmode means font
> > rendering is done via (fixed function in those times) hardware scanout
> > engine. Of course having only to update 2 bytes per character was a huge
> > saving early on. Likely this is also before vesa VBE was reliable.
> > 
> > So i guess the point where this all starts going wrong allowing the X parts
> > of the api to be combined with FB based rendering at all? Sounds the only
> > user didn't use that combination and so it was never tested?
> > 
> > Then again, this all relates to hardware from 20 years ago...
> 
> Imo userspace modesetting should be burned down anywhere we can. We've
> gotten away with this in drivers/gpu by just seamlessly transitioning to
> kernel drivers.
> 
> Since th only userspace we've found seems to be able to cope if this ioctl
> doesn't do anything, my vote goes towards ripping it out completely and
> doing nothing in there. Only question is whether we should error or fail
> with a silent success: Former is safer, latter can avoid a few regression
> reports since the userspace tools keep "working", and usually people don't
> notice for stuff this old. It worked in drivers/gpu :-)

This patch just ignores the ioctl and keeps on going, so userspace
"shouldn't" notice it :)

And it's in linux-next now, so all should be good.

thanks,

greg k-h

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2020-09-29 17:10                     ` Greg KH
@ 2021-04-11 21:43                       ` Maciej W. Rozycki
  2021-04-11 22:15                         ` Linus Torvalds
  0 siblings, 1 reply; 18+ messages in thread
From: Maciej W. Rozycki @ 2021-04-11 21:43 UTC (permalink / raw)
  To: Greg KH
  Cc: Martin Hostettler, Tetsuo Handa, jirislaby, Peilin Ye, syzbot,
	b.zolnierkie, deller, syzkaller-bugs, Linus Torvalds, dri-devel,
	linux-fbdev, linux-kernel, George Kennedy

On Tue, 29 Sep 2020, Greg KH wrote:

> > > > >> VT_RESIZEX was introduced in Linux 1.3.3, but it is unclear that what
> > > > >> comes to the "+ more" part, and I couldn't find a user of VT_RESIZEX.
> > > > >>
> > > > > 
> > > > > It seems this is/was used by "svgatextmode" which seems to be at
> > > > > http://www.ibiblio.org/pub/Linux/utils/console/
> > > > > 
> > > > > Not sure if that kind of software still has a chance to work nowadays.
> > > > > 
> > > > 
> > > > Thanks for the information.
> > > > 
> > > > It seems that v.v_vlin = curr_textmode->VDisplay / (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1)
> > > > and v.v_clin = curr_textmode->FontHeight . Thus, v.v_clin is font's height and seems to be non-zero.
> > > > But according to https://bugs.gentoo.org/19485 , people are using kernel framebuffer instead.
> > > > 
> > > 
> > > Yes, this seems to be from pre framebuffer times.
> > > 
> > > Back in the days "svga" was the wording you got for "pokes svga card
> > > hardware registers from userspace drivers". And textmode means font
> > > rendering is done via (fixed function in those times) hardware scanout
> > > engine. Of course having only to update 2 bytes per character was a huge
> > > saving early on. Likely this is also before vesa VBE was reliable.
> > > 
> > > So i guess the point where this all starts going wrong allowing the X parts
> > > of the api to be combined with FB based rendering at all? Sounds the only
> > > user didn't use that combination and so it was never tested?
> > > 
> > > Then again, this all relates to hardware from 20 years ago...
> > 
> > Imo userspace modesetting should be burned down anywhere we can. We've
> > gotten away with this in drivers/gpu by just seamlessly transitioning to
> > kernel drivers.
> > 
> > Since th only userspace we've found seems to be able to cope if this ioctl
> > doesn't do anything, my vote goes towards ripping it out completely and
> > doing nothing in there. Only question is whether we should error or fail
> > with a silent success: Former is safer, latter can avoid a few regression
> > reports since the userspace tools keep "working", and usually people don't
> > notice for stuff this old. It worked in drivers/gpu :-)
> 
> This patch just ignores the ioctl and keeps on going, so userspace
> "shouldn't" notice it :)
> 
> And it's in linux-next now, so all should be good.

 So it does trigger with vgacon and my old server, which I have started 
experimenting with and for a start I have switched to a new kernel for an 
unrelated purpose (now that I have relieved it from all its usual tasks 
except for the last remaining one for which I haven't got the required 
user software ported to the new system yet):

"struct vt_consize"->v_vlin is ignored. Please report if you need this.
"struct vt_consize"->v_clin is ignored. Please report if you need this.

It continues using svgatextmode with its glass (CRT) VT to set my usual 
80x37 text mode (720x576 pixel resolution) by manipulating the VGA clock 
chip and the CRT controller appropriately for a nice refresh rate of 85Hz:

Chipset = `TVGA8900', Textmode clock = 44.90 MHz, 80x37 chars, CharCell = 9x16. Refresh = 52.51kHz/84.7Hz.

 Indeed the piece of software became less usable around Y2K as clock chip 
support stopped being added to svgatextmode for new video adapters, but 
with the advent of LCD technology and its disregard for the refresh rate 
previously driven by the pixel clock the program got its second life and I 
have used it ever since with its plain VGA driver by just manipulating the 
CRTC for the resolution required:

Chipset = `VGA', Textmode clock = 28.32 MHz, 80x37 chars, CharCell = 9x16. Refresh = 31.47kHz/49.0Hz.

(that would still work with a standard 800x600 SVGA CRT, but the refresh 
rate would make anyone's eyes cry soon; with LCD it's just awesome, and 
the VGA emulation of the actual graphics adapter turns it at the video 
output into a 1600x1200 picture at the horizontal and vertical rates of 
75KHz and 60Hz respectively, making the text produced on LCD outstanding 
while showing about the right amount of it).

 But I'm currently ~160km/100mi away from the server I have triggered this 
message with, so I cannot easily check what's going on with its VT.  And I 
can't fiddle with my production laptop (ThinkPad P51) I have with me that 
I also use svgatextmode with so much as to reboot it with a new kernel 
(plain Debian 4.19.16-1~bpo9+1 still here).

 So what's the supposed impact of this change that prompted the inclusion 
of the messages?  I can port svgatextmode (it's my own compilation anyway) 
if that is required for it to continue working correctly, but I need to 
understand the circumstances here.  I have failed to find a satisfactory 
alternative solution to vgacon and svgatextmode; the main showstopper is 
the IBM's hardware trick for a 9x16 character cell that I rely on.

  Maciej

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2021-04-11 21:43                       ` Maciej W. Rozycki
@ 2021-04-11 22:15                         ` Linus Torvalds
  2021-04-12  7:01                           ` Daniel Vetter
  0 siblings, 1 reply; 18+ messages in thread
From: Linus Torvalds @ 2021-04-11 22:15 UTC (permalink / raw)
  To: Maciej W. Rozycki
  Cc: Greg KH, Martin Hostettler, Tetsuo Handa, Jiri Slaby, Peilin Ye,
	syzbot, Bartlomiej Zolnierkiewicz, Helge Deller, syzkaller-bugs,
	dri-devel, Linux Fbdev development list,
	Linux Kernel Mailing List, George Kennedy

On Sun, Apr 11, 2021 at 2:43 PM Maciej W. Rozycki <macro@orcam.me.uk> wrote:
>
>  So it does trigger with vgacon and my old server, which I have started
> experimenting with and for a start I have switched to a new kernel for an
> unrelated purpose (now that I have relieved it from all its usual tasks
> except for the last remaining one for which I haven't got the required
> user software ported to the new system yet):
>
> "struct vt_consize"->v_vlin is ignored. Please report if you need this.
> "struct vt_consize"->v_clin is ignored. Please report if you need this.

Note that it's entirely possible that things continue to work well
despite this warning. It's unclear to me from your email if you
actually see any difference (and apparently you're not able to see it
right now due to not being close to the machine).

The fact that v_vlin/v_clin are ignored doesn't necessarily mean that
they are different from what they were before, so the warning may be a
non-issue.

> It continues using svgatextmode with its glass (CRT) VT to set my usual
> 80x37 text mode (720x576 pixel resolution) by manipulating the VGA clock
> chip and the CRT controller appropriately for a nice refresh rate of 85Hz:
>
> Chipset = `TVGA8900', Textmode clock = 44.90 MHz, 80x37 chars, CharCell = 9x16. Refresh = 52.51kHz/84.7Hz.

That doesn't seem necessarily wrong to me.

>  So what's the supposed impact of this change that prompted the inclusion
> of the messages?

There _may_ be no impact at all apart from the messages.

The code _used_ to set the scan lines (v_vlin) and font height
(v_clin) from those numbers if they were non-zero, and now it just
ignores them and warns instead.

The code now just sets the font height from the actual font size when
the font is set. Which is honestly the only thing that ever made
sense. Trying to set it with v_clin is ignored, but it's entirely
possible - maybe even likely - that your user of VT_RESIZEX sets it to
the same values it already has.

Exactly because setting a font line number to anything else than the
font size isn't exactly sensible.

But if your screen looks different than it used to, that is obviously
interesting and says something actually changed (outside of the
message itself).

           Linus

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2021-04-11 22:15                         ` Linus Torvalds
@ 2021-04-12  7:01                           ` Daniel Vetter
  2021-04-12 13:30                             ` Maciej W. Rozycki
  0 siblings, 1 reply; 18+ messages in thread
From: Daniel Vetter @ 2021-04-12  7:01 UTC (permalink / raw)
  To: Linus Torvalds
  Cc: Maciej W. Rozycki, syzbot, Linux Fbdev development list,
	Bartlomiej Zolnierkiewicz, Tetsuo Handa, Greg KH, Helge Deller,
	syzkaller-bugs, Linux Kernel Mailing List, dri-devel,
	Martin Hostettler, George Kennedy, Jiri Slaby, Peilin Ye

On Mon, Apr 12, 2021 at 12:15 AM Linus Torvalds
<torvalds@linux-foundation.org> wrote:
>
> On Sun, Apr 11, 2021 at 2:43 PM Maciej W. Rozycki <macro@orcam.me.uk> wrote:
> >
> >  So it does trigger with vgacon and my old server, which I have started
> > experimenting with and for a start I have switched to a new kernel for an
> > unrelated purpose (now that I have relieved it from all its usual tasks
> > except for the last remaining one for which I haven't got the required
> > user software ported to the new system yet):
> >
> > "struct vt_consize"->v_vlin is ignored. Please report if you need this.
> > "struct vt_consize"->v_clin is ignored. Please report if you need this.
>
> Note that it's entirely possible that things continue to work well
> despite this warning. It's unclear to me from your email if you
> actually see any difference (and apparently you're not able to see it
> right now due to not being close to the machine).

Original search didn't turn up any users of VT_RESIZEX, this is the
first. And looking at the source code I think we could outright remove
support for VT_RESIZEX (but make it silent) and everything should keep
working:

        /*
         * ALWAYS do a VT_RESIZE, even if we already did a VT_RESIZEX
on a 1.3.3 or higher kernel,
         * until those kernel programmers make this unambiguous
         */

       if (do_VT_RESIZE(curr_textmode->cols, curr_textmode->rows,
resize1x1)) sresize=TRUE;

       if (check_kernel_version(1,3,3, "VT_RESIZEX"))
         {
           /*
            * VDisplay must de divided by 2 for DoubleScan modes,
            * or VT_RESIZEX will fail -- until someone fixes the kernel
            * so it understands about doublescan modes.
            */
           if (do_VT_RESIZEX(curr_textmode->cols,
                             curr_textmode->rows,
                             curr_textmode->VDisplay /
(MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1),
                             curr_textmode->FontHeight,
                             curr_textmode->HDisplay/8*curr_textmode->FontWidth,
                             curr_textmode->FontWidth, resize1x1)) sresize=TRUE;
         }

The functions are just straightforward wrappers. There's also no cvs
repo, changelog or old releases before 2000 that would shed some light
on why this code even exists.

I think we can just tune down the pr_info_once to pr_debug and done.
Maybe a comment about where the single user we're aware of is.
-Daniel

>
> The fact that v_vlin/v_clin are ignored doesn't necessarily mean that
> they are different from what they were before, so the warning may be a
> non-issue.
>
> > It continues using svgatextmode with its glass (CRT) VT to set my usual
> > 80x37 text mode (720x576 pixel resolution) by manipulating the VGA clock
> > chip and the CRT controller appropriately for a nice refresh rate of 85Hz:
> >
> > Chipset = `TVGA8900', Textmode clock = 44.90 MHz, 80x37 chars, CharCell = 9x16. Refresh = 52.51kHz/84.7Hz.
>
> That doesn't seem necessarily wrong to me.
>
> >  So what's the supposed impact of this change that prompted the inclusion
> > of the messages?
>
> There _may_ be no impact at all apart from the messages.
>
> The code _used_ to set the scan lines (v_vlin) and font height
> (v_clin) from those numbers if they were non-zero, and now it just
> ignores them and warns instead.
>
> The code now just sets the font height from the actual font size when
> the font is set. Which is honestly the only thing that ever made
> sense. Trying to set it with v_clin is ignored, but it's entirely
> possible - maybe even likely - that your user of VT_RESIZEX sets it to
> the same values it already has.
>
> Exactly because setting a font line number to anything else than the
> font size isn't exactly sensible.
>
> But if your screen looks different than it used to, that is obviously
> interesting and says something actually changed (outside of the
> message itself).
>
>            Linus
> _______________________________________________
> dri-devel mailing list
> dri-devel@lists.freedesktop.org
> https://lists.freedesktop.org/mailman/listinfo/dri-devel



-- 
Daniel Vetter
Software Engineer, Intel Corporation
http://blog.ffwll.ch

^ permalink raw reply	[flat|nested] 18+ messages in thread

* Re: [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE
  2021-04-12  7:01                           ` Daniel Vetter
@ 2021-04-12 13:30                             ` Maciej W. Rozycki
  0 siblings, 0 replies; 18+ messages in thread
From: Maciej W. Rozycki @ 2021-04-12 13:30 UTC (permalink / raw)
  To: Daniel Vetter
  Cc: Linus Torvalds, syzbot, Linux Fbdev development list,
	Bartlomiej Zolnierkiewicz, Tetsuo Handa, Greg KH, Helge Deller,
	syzkaller-bugs, Linux Kernel Mailing List, dri-devel,
	Martin Hostettler, George Kennedy, Jiri Slaby, Peilin Ye

On Mon, 12 Apr 2021, Daniel Vetter wrote:

> > Note that it's entirely possible that things continue to work well
> > despite this warning. It's unclear to me from your email if you
> > actually see any difference (and apparently you're not able to see it
> > right now due to not being close to the machine).
> 
> Original search didn't turn up any users of VT_RESIZEX, this is the
> first. And looking at the source code I think we could outright remove
> support for VT_RESIZEX (but make it silent) and everything should keep
> working:
> 
>         /*
>          * ALWAYS do a VT_RESIZE, even if we already did a VT_RESIZEX
> on a 1.3.3 or higher kernel,
>          * until those kernel programmers make this unambiguous
>          */
> 
>        if (do_VT_RESIZE(curr_textmode->cols, curr_textmode->rows,
> resize1x1)) sresize=TRUE;
> 
>        if (check_kernel_version(1,3,3, "VT_RESIZEX"))
>          {
>            /*
>             * VDisplay must de divided by 2 for DoubleScan modes,
>             * or VT_RESIZEX will fail -- until someone fixes the kernel
>             * so it understands about doublescan modes.
>             */
>            if (do_VT_RESIZEX(curr_textmode->cols,
>                              curr_textmode->rows,
>                              curr_textmode->VDisplay /
> (MOFLG_ISSET(curr_textmode, ATTR_DOUBLESCAN) ? 2 : 1),
>                              curr_textmode->FontHeight,
>                              curr_textmode->HDisplay/8*curr_textmode->FontWidth,
>                              curr_textmode->FontWidth, resize1x1)) sresize=TRUE;
>          }
> 
> The functions are just straightforward wrappers. There's also no cvs
> repo, changelog or old releases before 2000 that would shed some light
> on why this code even exists.

 I did some archaeology then, using a local copy of the linux-mips.org 
Linux tree that has historic information imported from the old oss.sgi.com 
MIPS/Linux CVS repo.  According to that the ioctl was added with or 
shortly before 2.1.14:

commit beb116954b9b7f3bb56412b2494b562f02b864b1
Author: Ralf Baechle <ralf@linux-mips.org>
Date:   Tue Jan 7 02:33:00 1997 +0000

    Import of Linux/MIPS 2.1.14

and, importantly, it was used to set some parameters: 

		if ( vlin )
		  video_scan_lines = vlin;
		if ( clin )
		  video_font_height = clin;

used by `con_adjust_height' in drivers/char/vga.c: `video_scan_lines' to 
set the vertical display limit (so that it is a whole multiple of the new 
font height) and `video_font_height' to set the cursor scan lines in the 
CRTC.  The function was used by the PIO_FONTX and PIO_FONTRESET VT ioctls 
at that point.

 That code was moved to `vgacon_adjust_height' in drivers/video/vgacon.c 
and then drivers/video/console/vgacon.c.  The code is still there, serving 
the KDFONTOP ioctl.

 With:

commit 9736a3546de7b6a2b16ad93539e4b3ac72b385bb
Author: Ralf Baechle <ralf@linux-mips.org>
Date:   Thu Jun 5 10:06:35 2003 +0000

    Merge with Linux 2.5.66.

the parameters were moved into `struct vc_data':

 		if (vlin)
-			video_scan_lines = vlin;
+			vc->vc_scan_lines = vlin;
 		if (clin)
-			video_font_height = clin;
+			vc->vc_font.height = clin;

and this piece of code to set them only removed with the change discussed 
here.

 So without even looking at the VT, which I'll surely get to eventually, I 
conclude this change regresses font resizing (KD_FONT_OP_SET) once a new 
resolution has been set with svgatextmode.  I think this change needs to 
be reverted, especially as the problematic PIO_FONT ioctl referred has 
been since removed with commit ff2047fb755d ("vt: drop old FONT ioctls").

  Maciej

^ permalink raw reply	[flat|nested] 18+ messages in thread

end of thread, other threads:[~2021-04-12 13:30 UTC | newest]

Thread overview: 18+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-02-23 17:30 KASAN: use-after-free Read in bit_putcs syzbot
2020-09-26  2:03 ` syzbot
2020-09-26 16:25   ` Tetsuo Handa
2020-09-26 19:39     ` Peilin Ye
2020-09-27  0:25     ` Tetsuo Handa
2020-09-27  8:28       ` Tetsuo Handa
2020-09-27  9:27         ` Peilin Ye
2020-09-27 11:46           ` [PATCH] vt_ioctl: make VT_RESIZEX behave like VT_RESIZE Tetsuo Handa
2020-09-27 12:06             ` Greg KH
2020-09-28 17:59             ` Martin Hostettler
2020-09-29  1:12               ` Tetsuo Handa
2020-09-29 10:52                 ` Martin Hostettler
2020-09-29 16:56                   ` Daniel Vetter
2020-09-29 17:10                     ` Greg KH
2021-04-11 21:43                       ` Maciej W. Rozycki
2021-04-11 22:15                         ` Linus Torvalds
2021-04-12  7:01                           ` Daniel Vetter
2021-04-12 13:30                             ` Maciej W. Rozycki

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).