The dev3_register_work delayed work item is initialized within
alps_reconnect() and scheduled upon receipt of the first bare
PS/2 packet from an external PS/2 device connected to the ALPS
touchpad. During device detachment, the original implementation
calls flush_workqueue() in psmouse_disconnect() to ensure
completion of dev3_register_work. However, the flush_workqueue()
in psmouse_disconnect() only blocks and waits for work items that
were already queued to the workqueue prior to its invocation. Any
work items submitted after flush_workqueue() is called are not
included in the set of tasks that the flush operation awaits.
This means that after flush_workqueue() has finished executing,
the dev3_register_work could still be scheduled. Although the
psmouse state is set to PSMOUSE_CMD_MODE in psmouse_disconnect(),
the scheduling of dev3_register_work remains unaffected.
The race condition can occur as follows:
CPU 0 (cleanup path) | CPU 1 (delayed work)
psmouse_disconnect() |
psmouse_set_state() |
flush_workqueue() | alps_report_bare_ps2_packet()
alps_disconnect() | psmouse_queue_work()
kfree(priv); // FREE | alps_register_bare_ps2_mouse()
| priv = container_of(work...); // USE
| priv->dev3 // USE
Add disable_delayed_work_sync() in alps_disconnect() to ensure
that dev3_register_work is properly canceled and prevented from
executing after the alps_data structure has been deallocated.
This bug is identified by static analysis.
Fixes:
|
||
|---|---|---|
| .. | ||
| Kconfig | ||
| Makefile | ||
| alps.c | ||
| alps.h | ||
| amimouse.c | ||
| appletouch.c | ||
| atarimouse.c | ||
| bcm5974.c | ||
| byd.c | ||
| byd.h | ||
| cyapa.c | ||
| cyapa.h | ||
| cyapa_gen3.c | ||
| cyapa_gen5.c | ||
| cyapa_gen6.c | ||
| cypress_ps2.c | ||
| cypress_ps2.h | ||
| elan_i2c.h | ||
| elan_i2c_core.c | ||
| elan_i2c_i2c.c | ||
| elan_i2c_smbus.c | ||
| elantech.c | ||
| elantech.h | ||
| focaltech.c | ||
| focaltech.h | ||
| gpio_mouse.c | ||
| hgpk.c | ||
| hgpk.h | ||
| inport.c | ||
| lifebook.c | ||
| lifebook.h | ||
| logibm.c | ||
| logips2pp.c | ||
| logips2pp.h | ||
| maplemouse.c | ||
| pc110pad.c | ||
| psmouse-base.c | ||
| psmouse-smbus.c | ||
| psmouse.h | ||
| rpcmouse.c | ||
| sentelic.c | ||
| sentelic.h | ||
| sermouse.c | ||
| synaptics.c | ||
| synaptics.h | ||
| synaptics_i2c.c | ||
| synaptics_usb.c | ||
| touchkit_ps2.c | ||
| touchkit_ps2.h | ||
| trackpoint.c | ||
| trackpoint.h | ||
| vmmouse.c | ||
| vmmouse.h | ||
| vsxxxaa.c | ||