linux/drivers/hid
David Herrmann 4ea5454203 HID: Fix race condition between driver core and ll-driver
HID low level drivers register new devices with the HID core which then
adds the devices to the HID bus. The HID bus normally immediately probes
an appropriate driver which then handles HID input for this device.
The ll driver now uses the hid_input_report() function to report input
events for a specific device. However, if the HID bus unloads the driver
at the same time (for instance via a call to
 /sys/bus/hid/devices/<dev>/unbind) then the hdev->driver pointer may be
used by hid_input_report() and hid_device_remove() at the same time
which may cause hdev->driver to point to invalid memory.

This fix adds a semaphore to every hid device which protects
hdev->driver from asynchronous access. This semaphore is locked during
driver *_probe and *_remove and also inside hid_input_report(). The
*_probe and *_remove functions may sleep so the semaphore is good here,
however, hid_input_report() is in atomic context and hence only uses
down_trylock(). If it cannot acquire the lock it simply drops the input
package.

The low-level drivers report input events synchronously so
hid_input_report() should never be entered twice at the same time on the
same device. Hence, the lock should always be available. But if the
driver is currently probed/removed then the lock is not available and
dropping the package should be safe because this is what would have
happened if the package arrived some milliseconds earlier/later.

This also fixes another race condition while probing drivers:
First the *_probe function of the driver is called and only if that
succeeds, the related input device of hidinput is registered. If the low
level driver reports input events after the *_probe function returned
but before the input device is registered, then a NULL pointer
dereference will occur. (Equivalently on driver remove function).
This is not possible anymore, since the semaphore lock drops all
incoming packages until the driver/device is fully initialized.

Signed-off-by: David Herrmann <dh.herrmann@googlemail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.cz>
2011-08-10 14:02:07 +02:00
..
usbhid Merge branches 'roccat', 'upstream' and 'wiimote' into for-linus 2011-07-22 22:47:08 +02:00
hid-a4tech.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-apple.c Input: bcm5974 - add support for MacBookPro8 2011-03-12 20:37:30 -08:00
hid-axff.c HID: ACRUX - add missing hid_hw_stop() in ax_probe() error path 2011-07-14 11:42:53 +02:00
hid-belkin.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-cherry.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-chicony.c HID: adding __init/__exit macros to module init/exit functions 2009-07-23 01:28:01 +02:00
hid-core.c HID: Fix race condition between driver core and ll-driver 2011-08-10 14:02:07 +02:00
hid-cypress.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-debug.c Fix common misspellings 2011-03-31 11:26:23 -03:00
hid-dr.c HID: add support for DragonRise PID 0011 gamepad 2011-02-01 11:01:06 +01:00
hid-elecom.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-emsff.c HID: emsff: properly handle emsff_init failure 2011-07-20 11:55:18 +02:00
hid-ezkey.c HID: adding __init/__exit macros to module init/exit functions 2009-07-23 01:28:01 +02:00
hid-gaff.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-gyration.c HID: Add teletext/color keys - gyration remote - EU version (GYAR3101CKDE) 2011-02-15 10:29:57 +01:00
hid-holtekff.c HID: add FF support for Holtek On Line Grip based gamepads 2011-06-27 12:40:00 +02:00
hid-ids.h Merge branches 'roccat', 'upstream' and 'wiimote' into for-linus 2011-07-22 22:47:08 +02:00
hid-input.c HID: assorted usage updates from hut 1.12 2011-05-18 17:07:34 +02:00
hid-kensington.c HID: adding __init/__exit macros to module init/exit functions 2009-07-23 01:28:01 +02:00
hid-keytouch.c HID: add support for Keytouch IEC 60945 2011-02-17 15:12:45 +01:00
hid-kye.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-lcpower.c HID: hid-lcpower: fix key mapping 2011-02-13 15:04:51 +01:00
hid-lg2ff.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-lg3ff.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-lg4ff.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-lg.c HID: Fix Logitech Driving Force Pro wheel 2011-06-07 15:48:05 +02:00
hid-lg.h HID: Add support for Logitech Speed Force Wireless gaming wheel 2010-09-22 13:25:39 +02:00
hid-lgff.c Merge branches 'doc', 'multitouch', 'upstream' and 'upstream-fixes' into for-linus 2011-05-23 12:49:25 +02:00
hid-magicmouse.c Revert "HID: magicmouse: ignore 'ivalid report id' while switching modes" 2011-06-16 12:21:34 +02:00
hid-microsoft.c HID: fix horizontal wheel for ms comfort mouse 4500 2011-07-12 10:31:56 +02:00
hid-monterey.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-multitouch.c Merge branches 'roccat', 'upstream' and 'wiimote' into for-linus 2011-07-22 22:47:08 +02:00
hid-ntrig.c HID: hid-ntrig: init settle and mode check 2011-03-14 13:10:13 +01:00
hid-ortek.c HID: add support for Skycable 0x3f07 wireless presenter 2011-03-21 16:12:23 +01:00
hid-petalynx.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-picolcd.c Merge branch 'master' into upstream. 2011-05-18 17:06:49 +02:00
hid-pl.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-prodikeys.c HID: prodikeys: kfree() NULL pointer cleanup 2011-08-04 23:51:29 +02:00
hid-quanta.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-roccat-arvo.c HID: roccat: fix NULL pointer dereference, add range checks 2011-06-13 13:06:23 +02:00
hid-roccat-arvo.h HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat-common.c HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat-common.h HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat-kone.c HID: roccat: fix NULL pointer dereference, add range checks 2011-06-13 13:06:23 +02:00
hid-roccat-kone.h HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat-koneplus.c HID: roccat: fix NULL pointer dereference, add range checks 2011-06-13 13:06:23 +02:00
hid-roccat-koneplus.h HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat-kovaplus.c HID: roccat: fix NULL pointer dereference, add range checks 2011-06-13 13:06:23 +02:00
hid-roccat-kovaplus.h HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat-pyra.c HID: roccat: fix NULL pointer dereference, add range checks 2011-06-13 13:06:23 +02:00
hid-roccat-pyra.h HID: roccat: correction and cleanup of HID feature reports 2011-06-13 12:52:57 +02:00
hid-roccat.c HID: roccat: Rename header roccat.h -> hid-roccat.h 2011-02-03 16:37:28 +01:00
hid-samsung.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-sjoy.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-sony.c HID: hid-sony: fix endiannes of Sixaxis accel/gyro values 2011-06-13 13:21:30 +02:00
hid-speedlink.c HID: Add driver to fix Speedlink VAD Cezanne support 2011-06-08 09:45:37 +02:00
hid-sunplus.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-tmff.c Merge branch 'master' into upstream 2010-12-10 15:19:18 +01:00
hid-topseed.c HID: Add support for Perixx PERIBOARD-707 (Plus) 2010-11-25 15:59:02 +01:00
hid-twinhan.c HID: add __init/__exit macros to twinhan.c 2009-09-29 13:58:20 +02:00
hid-uclogic.c HID: uclogic: Add support for UC-Logic WP1062 2011-07-11 14:37:24 +02:00
hid-wacom.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-waltop.c HID: waltop: add support for Waltop Slim Tablet 12.1 inch 2010-10-01 15:34:05 +02:00
hid-wiimote.c HID: wiimote: Add sysfs support to wiimote driver 2011-07-11 14:30:24 +02:00
hid-zpff.c HID: Add and use hid_<level>: dev_<level> equivalents 2010-12-10 15:10:38 +01:00
hid-zydacron.c HID: zydacron: kfree() NULL pointer cleanup 2011-08-04 23:51:29 +02:00
hidraw.c HID: 'name' and 'phys' in 'struct hid_device' can never be NULL 2011-05-18 13:23:31 +02:00
Kconfig Merge branches 'roccat', 'upstream' and 'wiimote' into for-linus 2011-07-22 22:47:08 +02:00
Makefile Merge branches 'roccat', 'upstream' and 'wiimote' into for-linus 2011-07-22 22:47:08 +02:00