Hi vmwgfx maintainers,
An out-of-bound access in vmwgfx specific framebuffer implementation can
be easily triggered by fbterm (a framebuffer terminal emulator) when it
is going to scroll screen.
With some debugging, it seems that vmw_fb_dirty_flush() cannot handle
the vinfo.yoffset correctly after calling `ioctl(fbdev_fd,
FBIOPAN_DISPLAY, &vinfo);`, and then subsequent access to the mapped
memory area causes the oops.
As current mainline vmwgfx implementation (in Linux 6.2-rc) has removed
this framebuffer implementation, this bug can be triggered only in Linux
stable. I have tested it with vanilla 6.1.8 and 5.10.165 and they all oops.
This bug is reported in
<https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=1029602> first, and
the maintainer there suggests me to report this issue to upstream :)
Relevant information (for self-compiled Linux 6.1.8):
- /proc/version: Linux version 6.1.8 (tao@mira) (gcc (Debian 10.2.1-6)
10.2.1 20210110, GNU ld (GNU Binutils for Debian) 2.35.2) #7 SMP
PREEMPT_DYNAMIC Mon Jan 30 21:09:02 CST 2023
- Linux distribution: Debian GNU/Linux 11 (bullseye)
- Architecture (uname -mi): x86_64 unknown
- Virtualization software: VMware Fusion 13 Player
- How to reproduce:
1. Install (or compile) fbterm
2. Run fbterm under a tty (by a user with read & write permission to
/dev/fb0, usually users in video group), and try to make it scroll (for
example by pressing Enter for a few seconds)
3. The graphics hang and it oops.
- decoded oops message:
[ 31.519514] BUG: unable to handle page fault for address:
ffffa7c5019d6000
[ 31.519843] #PF: supervisor write access in kernel mode
[ 31.520149] #PF: error_code(0x0002) - not-present page
[ 31.520453] PGD 1000067 P4D 1000067 PUD 11bc067 PMD 31f0d067 PTE 0
[ 31.520784] Oops: 0002 [#1] PREEMPT SMP PTI
[ 31.521022] CPU: 0 PID: 7 Comm: kworker/0:0 Kdump: loaded Not tainted
6.1.8 #7
[ 31.521266] Hardware name: VMware, Inc. VMware Virtual Platform/440BX
Desktop Reference Platform, BIOS 6.00 11/12/2020
[ 31.521796] Workqueue: events vmw_fb_dirty_flush [vmwgfx]
[ 31.522080] RIP: 0010:memcpy_orig
(/home/tao/Downloads/linux-6.1.8/arch/x86/lib/memcpy_64.S:85)
[ 31.522396] Code: 00 48 89 f8 48 83 fa 20 72 7e 40 38 fe 7c 35 48 83 ea
20 48 83 ea 20 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 8b 5e 18 48 8d 76 20
<4c> 89 07 4c 89 4f 08 4c 89 57 10 4c 89 5f 18 48 8d 7f 20 73 d4 83
All code
========
0: 00 48 89 add %cl,-0x77(%rax)
3: f8 clc
4: 48 83 fa 20 cmp $0x20,%rdx
8: 72 7e jb 0x88
a: 40 38 fe cmp %dil,%sil
d: 7c 35 jl 0x44
f: 48 83 ea 20 sub $0x20,%rdx
13: 48 83 ea 20 sub $0x20,%rdx
17: 4c 8b 06 mov (%rsi),%r8
1a: 4c 8b 4e 08 mov 0x8(%rsi),%r9
1e: 4c 8b 56 10 mov 0x10(%rsi),%r10
22: 4c 8b 5e 18 mov 0x18(%rsi),%r11
26: 48 8d 76 20 lea 0x20(%rsi),%rsi
2a:* 4c 89 07 mov %r8,(%rdi) <-- trapping instruction
2d: 4c 89 4f 08 mov %r9,0x8(%rdi)
31: 4c 89 57 10 mov %r10,0x10(%rdi)
35: 4c 89 5f 18 mov %r11,0x18(%rdi)
39: 48 8d 7f 20 lea 0x20(%rdi),%rdi
3d: 73 d4 jae 0x13
3f: 83 .byte 0x83
Code starting with the faulting instruction
===========================================
0: 4c 89 07 mov %r8,(%rdi)
3: 4c 89 4f 08 mov %r9,0x8(%rdi)
7: 4c 89 57 10 mov %r10,0x10(%rdi)
b: 4c 89 5f 18 mov %r11,0x18(%rdi)
f: 48 8d 7f 20 lea 0x20(%rdi),%rdi
13: 73 d4 jae 0xffffffffffffffe9
15: 83 .byte 0x83
[ 31.523208] RSP: 0018:ffffa7c50005be10 EFLAGS: 00010202
[ 31.523555] RAX: ffffa7c5019d5c00 RBX: 0000000000000c80 RCX:
0000000000000c80
[ 31.523841] RDX: 0000000000000840 RSI: ffffa7c500e73a20 RDI:
ffffa7c5019d6000
[ 31.524071] RBP: 0000000000000000 R08: 0000000000000000 R09:
0000000000000000
[ 31.524299] R10: 0000000000000000 R11: 0000000000000000 R12:
ffffa7c500e73600
[ 31.524525] R13: ffff97ba70af4cd8 R14: ffff97ba70b40000 R15:
ffff97ba70af4800
[ 31.524753] FS: 0000000000000000(0000) GS:ffff97ba91800000(0000)
knlGS:0000000000000000
[ 31.524981] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 31.525209] CR2: ffffa7c5019d6000 CR3: 0000000037a10002 CR4:
00000000003706f0
[ 31.525440] Call Trace:
[ 31.525670] <TASK>
[ 31.525900] vmw_fb_dirty_flush
(/home/tao/Downloads/linux-6.1.8/drivers/gpu/drm/vmwgfx/vmwgfx_fb.c:244)
vmwgfx
[ 31.526162] process_one_work
(/home/tao/Downloads/linux-6.1.8/kernel/workqueue.c:2289)
[ 31.526399] worker_thread
(/home/tao/Downloads/linux-6.1.8/./include/linux/list.h:292
/home/tao/Downloads/linux-6.1.8/kernel/workqueue.c:2437)
[ 31.526623] ? rescuer_thread
(/home/tao/Downloads/linux-6.1.8/kernel/workqueue.c:2379)
[ 31.526843] kthread
(/home/tao/Downloads/linux-6.1.8/kernel/kthread.c:376)
[ 31.527058] ? kthread_complete_and_exit
(/home/tao/Downloads/linux-6.1.8/kernel/kthread.c:331)
[ 31.527273] ret_from_fork
(/home/tao/Downloads/linux-6.1.8/arch/x86/entry/entry_64.S:306)
[ 31.527490] </TASK>
[ 31.527748] Modules linked in: xt_conntrack xt_MASQUERADE
nf_conntrack_netlink nfnetlink xfrm_user xfrm_algo xt_addrtype
iptable_filter iptable_nat nf_nat nf_conntrack nf_defrag_ipv6
nf_defrag_ipv4 br_netfilter bridge stp llc intel_rapl_msr
intel_rapl_common intel_pmc_core kvm_intel kvm irqbypass rapl
vmw_balloon joydev serio_raw pcspkr snd_ens1371 snd_ac97_codec ac97_bus
gameport snd_rawmidi snd_seq_device snd_pcm snd_timer snd soundcore sg
overlay vsock_loopback vmw_vsock_virtio_transport_common
vmw_vsock_vmci_transport vsock vmw_vmci evdev ac binfmt_misc parport_pc
nfsd ppdev fuse auth_rpcgss nfs_acl lp lockd grace parport configfs
sunrpc ip_tables x_tables autofs4 ext4 crc16 mbcache jbd2 btrfs
blake2b_generic xor raid6_pq zstd_compress libcrc32c crc32c_generic
dm_mirror dm_region_hash dm_log dm_mod hid_generic usbhid hid sd_mod
t10_pi crc64_rocksoft_generic crc64_rocksoft crc_t10dif
crct10dif_generic crc64 crct10dif_pclmul crct10dif_common crc32_pclmul
crc32c_intel
[ 31.527816] ghash_clmulni_intel sha512_ssse3 sha512_generic sr_mod
cdrom aesni_intel crypto_simd ata_generic cryptd vmwgfx xhci_pci
ata_piix drm_ttm_helper ttm mptspi psmouse mptscsih ehci_pci mptbase
drm_kms_helper uhci_hcd xhci_hcd ehci_hcd scsi_transport_spi libata
scsi_mod drm e1000 usbcore usb_common i2c_piix4 scsi_common button
[ 31.531626] CR2: ffffa7c5019d6000
[ 31.531892] ---[ end trace 0000000000000000 ]---
[ 31.532289] RIP: 0010:memcpy_orig
(/home/tao/Downloads/linux-6.1.8/arch/x86/lib/memcpy_64.S:85)
[ 31.532536] Code: 00 48 89 f8 48 83 fa 20 72 7e 40 38 fe 7c 35 48 83 ea
20 48 83 ea 20 4c 8b 06 4c 8b 4e 08 4c 8b 56 10 4c 8b 5e 18 48 8d 76 20
<4c> 89 07 4c 89 4f 08 4c 89 57 10 4c 89 5f 18 48 8d 7f 20 73 d4 83
All code
========
0: 00 48 89 add %cl,-0x77(%rax)
3: f8 clc
4: 48 83 fa 20 cmp $0x20,%rdx
8: 72 7e jb 0x88
a: 40 38 fe cmp %dil,%sil
d: 7c 35 jl 0x44
f: 48 83 ea 20 sub $0x20,%rdx
13: 48 83 ea 20 sub $0x20,%rdx
17: 4c 8b 06 mov (%rsi),%r8
1a: 4c 8b 4e 08 mov 0x8(%rsi),%r9
1e: 4c 8b 56 10 mov 0x10(%rsi),%r10
22: 4c 8b 5e 18 mov 0x18(%rsi),%r11
26: 48 8d 76 20 lea 0x20(%rsi),%rsi
2a:* 4c 89 07 mov %r8,(%rdi) <-- trapping instruction
2d: 4c 89 4f 08 mov %r9,0x8(%rdi)
31: 4c 89 57 10 mov %r10,0x10(%rdi)
35: 4c 89 5f 18 mov %r11,0x18(%rdi)
39: 48 8d 7f 20 lea 0x20(%rdi),%rdi
3d: 73 d4 jae 0x13
3f: 83 .byte 0x83
Code starting with the faulting instruction
===========================================
0: 4c 89 07 mov %r8,(%rdi)
3: 4c 89 4f 08 mov %r9,0x8(%rdi)
7: 4c 89 57 10 mov %r10,0x10(%rdi)
b: 4c 89 5f 18 mov %r11,0x18(%rdi)
f: 48 8d 7f 20 lea 0x20(%rdi),%rdi
13: 73 d4 jae 0xffffffffffffffe9
15: 83 .byte 0x83
[ 31.533338] RSP: 0018:ffffa7c50005be10 EFLAGS: 00010202
[ 31.533561] RAX: ffffa7c5019d5c00 RBX: 0000000000000c80 RCX:
0000000000000c80
[ 31.533784] RDX: 0000000000000840 RSI: ffffa7c500e73a20 RDI:
ffffa7c5019d6000
[ 31.534008] RBP: 0000000000000000 R08: 0000000000000000 R09:
0000000000000000
[ 31.534229] R10: 0000000000000000 R11: 0000000000000000 R12:
ffffa7c500e73600
[ 31.534447] R13: ffff97ba70af4cd8 R14: ffff97ba70b40000 R15:
ffff97ba70af4800
[ 31.534664] FS: 0000000000000000(0000) GS:ffff97ba91800000(0000)
knlGS:0000000000000000
[ 31.534884] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
[ 31.535105] CR2: ffffa7c5019d6000 CR3: 0000000037a10002 CR4:
00000000003706f0