[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
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.