Input: synaptics-rmi4 - fix GPF in suspend and resume when unbound

Transport drivers (such as rmi_i2c and rmi_spi) invoke
rmi_driver_suspend() and rmi_driver_resume() on their child rmi_dev
device during system power management events. However, transport drivers
are fully registered and operational even if the physical RMI driver
failed to bind or probe the rmi_dev device.

When rmi_driver_suspend() or rmi_driver_resume() is called on an unbound
rmi_dev, dev_get_drvdata() returns NULL. Calling rmi_disable_irq() or
rmi_enable_irq() without driver data attached causes a NULL pointer
dereference and General Protection Fault when attempting to lock
data->enabled_mutex.

Fix this by checking if driver data is attached to rmi_dev in
rmi_driver_suspend() and rmi_driver_resume(), exiting early if
no driver data is present.

Fixes: 2b6a321da9 ("Input: synaptics-rmi4 - add support for Synaptics RMI4 devices")
Reported-by: syzbot+09103639e39c989e3ed3@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=09103639e39c989e3ed3
Cc: stable@vger.kernel.org
Assisted-by: LLM
Link: https://patch.msgid.link/anQe8UiyUR4x0flD@google.com
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
This commit is contained in:
Dmitry Torokhov 2026-08-05 22:44:23 -07:00
parent 51cfe54f81
commit fe10579b6d

View File

@ -991,6 +991,15 @@ int rmi_driver_suspend(struct rmi_device *rmi_dev, bool enable_wake)
{
int retval;
/*
* Transport driver will try to suspend RMI device even if physical
* driver did not bind to the RMI device, because transport device
* (I2C, SPI) is fully registered and operational. Exit early if
* there is no driver data attached to the RMI device.
*/
if (!dev_get_drvdata(&rmi_dev->dev))
return 0;
retval = rmi_suspend_functions(rmi_dev);
if (retval)
dev_warn(&rmi_dev->dev, "Failed to suspend functions: %d\n",
@ -1005,6 +1014,10 @@ int rmi_driver_resume(struct rmi_device *rmi_dev, bool clear_wake)
{
int retval;
/* Skip if not fully bound to RMI driver */
if (!dev_get_drvdata(&rmi_dev->dev))
return 0;
rmi_enable_irq(rmi_dev, clear_wake);
retval = rmi_resume_functions(rmi_dev);