[PATCH v3 5/8] HID: hid-tmff: clean up usage of 'driver_data'
"Pawel Zalewski (The Capable Hub)" <[email protected]>
| Newsgroups | org.kernel.vger.linux-input,org.kernel.vger.linux-kernel |
|---|---|
| Message-ID | <20260727-mod-devicetable-hid_device_id-v3-5-980896ca283e@thegoodpenguin.co.uk> |
This module is using the 'hid_device_id::driver_data' field as a valid pointer to dereference. The hid subsystem supports injecting a 'new_id' device from the command line and so it is more convenient to have this value to be an integer - that way userspace can select a valid pointer within the driver via an index. Lets make this possible by storing an index to the table of pointers 'ff_bits_table' there as opposed to the pointer address directly. The retrieval is bounded at runtime by the 'ff_bits_table_index' enum to avoid dereferencing OOB objects. Signed-off-by: Pawel Zalewski (The Capable Hub) <[email protected]> --- drivers/hid/hid-tmff.c | 48 +++++++++++++++++++++++++++++++++++++----------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/drivers/hid/hid-tmff.c b/drivers/hid/hid-tmff.c index 423f395d01ac..93de756dd30e 100644 --- a/drivers/hid/hid-tmff.c +++ b/drivers/hid/hid-tmff.c @@ -34,6 +34,17 @@ static const signed short ff_joystick[] = { -1 }; +enum ff_bits_table_index { + FF_BITS_TABLE_RUMBLE, + FF_BITS_TABLE_JOYSTICK, + NUM_OF_FF_BITS_IN_TABLE +}; + +static const signed short *ff_bits_table[] = { + [FF_BITS_TABLE_RUMBLE] = ff_rumble, + [FF_BITS_TABLE_JOYSTICK] = ff_joystick +}; + #ifdef CONFIG_THRUSTMASTER_FF /* Usages for thrustmaster devices I know about */ @@ -210,9 +221,18 @@ static inline int tmff_init(struct hid_device *hid, const signed short *ff_bits) } #endif +static const signed short *get_ff_bits(enum ff_bits_table_index index) +{ + if (index >= NUM_OF_FF_BITS_IN_TABLE) + return NULL; + + return ff_bits_table[index]; +} + static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) { int ret; + const signed short *ff_bits = get_ff_bits(id->driver_data); ret = hid_parse(hdev); if (ret) { @@ -226,7 +246,13 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) goto err; } - tmff_init(hdev, (void *)id->driver_data); + if (!ff_bits) { + hid_err(hdev, "no ff_bits found\n"); + ret = -EINVAL; + goto err; + } + + tmff_init(hdev, ff_bits); return 0; err: @@ -235,25 +261,25 @@ static int tm_probe(struct hid_device *hdev, const struct hid_device_id *id) static const struct hid_device_id tm_devices[] = { { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb300), - .driver_data = (unsigned long)ff_rumble }, + .driver_data = FF_BITS_TABLE_RUMBLE }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb304), /* FireStorm Dual Power 2 (and 3) */ - .driver_data = (unsigned long)ff_rumble }, + .driver_data = FF_BITS_TABLE_RUMBLE }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, THRUSTMASTER_DEVICE_ID_2_IN_1_DT), /* Dual Trigger 2-in-1 */ - .driver_data = (unsigned long)ff_rumble }, + .driver_data = FF_BITS_TABLE_RUMBLE }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb323), /* Dual Trigger 3-in-1 (PC Mode) */ - .driver_data = (unsigned long)ff_rumble }, + .driver_data = FF_BITS_TABLE_RUMBLE }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb324), /* Dual Trigger 3-in-1 (PS3 Mode) */ - .driver_data = (unsigned long)ff_rumble }, + .driver_data = FF_BITS_TABLE_RUMBLE }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb605), /* NASCAR PRO FF2 Wheel */ - .driver_data = (unsigned long)ff_joystick }, + .driver_data = FF_BITS_TABLE_JOYSTICK }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb651), /* FGT Rumble Force Wheel */ - .driver_data = (unsigned long)ff_rumble }, + .driver_data = FF_BITS_TABLE_RUMBLE }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb653), /* RGT Force Feedback CLUTCH Raging Wheel */ - .driver_data = (unsigned long)ff_joystick }, + .driver_data = FF_BITS_TABLE_JOYSTICK }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb654), /* FGT Force Feedback Wheel */ - .driver_data = (unsigned long)ff_joystick }, + .driver_data = FF_BITS_TABLE_JOYSTICK }, { HID_USB_DEVICE(USB_VENDOR_ID_THRUSTMASTER, 0xb65a), /* F430 Force Feedback Wheel */ - .driver_data = (unsigned long)ff_joystick }, + .driver_data = FF_BITS_TABLE_JOYSTICK }, { } }; MODULE_DEVICE_TABLE(hid, tm_devices); -- 2.43.0