[PATCH v6 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create

From: Aldo Ariel Panzardo

Date: Fri Oct 16 2026 - 11:24:42 EST


Move try_module_get() and get_device() before input_ff_create() in
hid_haptic_init(). The original order placed them after
input_ff_create(), and failures went to input_free which called
input_ff_destroy() without ever setting ret. The caller saw ret == 0
on failure and kept a dangling pointer to the haptic struct.

With the references acquired first, all failure paths reach
stop_buffer_free directly. The flush/event save/restore is no longer
needed.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@xxxxxxxxxxxxxxx
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@xxxxxxxxx>
---
drivers/hid/hid-haptic.c | 33 ++++++++++++++-------------------
1 file changed, 14 insertions(+), 19 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 8760eeb..592b44e 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -419,8 +419,6 @@ int hid_haptic_init(struct hid_device *hdev,
};
const char *prefix = "hid-haptic";
char *name;
- int (*flush)(struct input_dev *dev, struct file *file);
- int (*event)(struct input_dev *dev, unsigned int type, unsigned int code, int value);

haptic->hdev = hdev;
haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
@@ -501,11 +499,23 @@ int hid_haptic_init(struct hid_device *hdev,

input_set_capability(dev, EV_FF, FF_HAPTIC);

- flush = dev->flush;
- event = dev->event;
+ if (!try_module_get(THIS_MODULE)) {
+ dev_err(&hdev->dev, "Failed to increase module count.\n");
+ ret = -ENODEV;
+ goto stop_buffer_free;
+ }
+ if (!get_device(&hdev->dev)) {
+ dev_err(&hdev->dev, "Failed to get hdev device.\n");
+ ret = -ENODEV;
+ module_put(THIS_MODULE);
+ goto stop_buffer_free;
+ }
+
ret = input_ff_create(dev, FF_MAX_EFFECTS);
if (ret) {
dev_err(&hdev->dev, "Failed to create ff device.\n");
+ put_device(&hdev->dev);
+ module_put(THIS_MODULE);
goto stop_buffer_free;
}

@@ -515,23 +525,8 @@ int hid_haptic_init(struct hid_device *hdev,
ff->playback = hid_haptic_playback;
ff->erase = hid_haptic_erase;
ff->destroy = hid_haptic_destroy;
- if (!try_module_get(THIS_MODULE)) {
- dev_err(&hdev->dev, "Failed to increase module count.\n");
- goto input_free;
- }
- if (!get_device(&hdev->dev)) {
- dev_err(&hdev->dev, "Failed to get hdev device.\n");
- module_put(THIS_MODULE);
- goto input_free;
- }
return 0;

-input_free:
- input_ff_destroy(dev);
- /* Restore dev flush and event */
- dev->flush = flush;
- dev->event = event;
- return ret;
stop_buffer_free:
kfree(haptic->stop_effect.report_buf);
haptic->stop_effect.report_buf = NULL;
--
2.53.0