[PATCH] fbdev: smscufx: bail out of ufx_set_vid_mode() when the device is gone
From: YuanZhe Liu
Date: Mon Nov 02 2026 - 02:22:55 EST
ufx_usb_disconnect() marks the device as virtualized and clears
usb_active, but the fbdev entry points that program the controller are
not serialized against it. ufx_handle_damage(), ufx_dpy_deferred_io()
and ufx_ops_ioctl() all return early while usb_active is clear;
ufx_set_vid_mode() does not, so a mode set or a blank request that
races with the disconnect keeps issuing control transfers through
dev->udev.
The usb_device is released once the disconnect callback returns, while
dev->udev is left pointing at it, so those transfers dereference a
stale pointer and fault in __create_pipe():
general protection fault, probably for non-canonical address
0xdffffc0000000006: 0000 [#1] SMP
KASAN: null-ptr-deref in range [0x0000000000000030-0x0000000000000037]
RIP: 0010:__create_pipe include/linux/usb.h:2031
Call Trace:
ufx_set_vid_mode
ufx_ops_set_par
fb_set_var
fb_set_var_from_user
store_rotate
Return -ENODEV from ufx_set_vid_mode() when the device is no longer
active, matching the check the other transmit paths already use. Both
callers, ufx_ops_set_par() and ufx_ops_blank(), handle the error: the
former skips the greenscreen fill and keeps the previous mode, the
latter already ignores the result.
The guard cannot live in ufx_reg_write()/ufx_reg_read() instead, since
probe programs the controller through ufx_config_ddr2(),
ufx_i2c_init(), ufx_setup_modes() and ufx_reg_set_bits() before it sets
usb_active.
Fixes: 3c8a63e22a08 ("Add support for SMSC UFX6000/7000 USB display adapters")
Cc: stable@xxxxxxxxxxxxxxx
Co-developed-by: Bin Yu <byu@xxxxxxxxxxxxx>
Signed-off-by: Bin Yu <byu@xxxxxxxxxxxxx>
Co-developed-by: Cheng Wen <wencheng@xxxxxxxxxxxxx>
Signed-off-by: Cheng Wen <wencheng@xxxxxxxxxxxxx>
Signed-off-by: YuanZhe Liu <25031212351@xxxxxxxxxxxxxxxxx>
---
drivers/video/fbdev/smscufx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 5704f60e1741..f1b640a5d712 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -661,8 +661,12 @@ static int ufx_set_vid_mode(struct ufx_data *dev, struct fb_var_screeninfo *var)
u32 temp;
u16 h_total, h_active, h_blank_start, h_blank_end, h_sync_start, h_sync_end;
u16 v_total, v_active, v_blank_start, v_blank_end, v_sync_start, v_sync_end;
+ int status;
+
+ if (!atomic_read(&dev->usb_active))
+ return -ENODEV;
- int status = ufx_reg_write(dev, 0x8028, 0);
+ status = ufx_reg_write(dev, 0x8028, 0);
check_warn_return(status, "ufx_set_vid_mode error disabling RGB pad");
status = ufx_reg_write(dev, 0x8024, 0);
--
2.34.1