mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v5 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
       [not found] <20261009103333.2476105-1-qwe.aldo@gmail.com>
@ 2026-10-16 13:55 ` Aldo Ariel Panzardo
  2026-10-16 13:55   ` [PATCH v5 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
                     ` (2 more replies)
  0 siblings, 3 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 13:55 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

Hi Benjamin,

Thanks for the feedback on v4.  Reworked as you asked -- devm_kzalloc
stays, a devm_add_action() handles teardown, and the try_module_get
reorder is now a separate patch.

Patch 1 moves try_module_get()/get_device() before input_ff_create()
so the old input_free error path (which returned ret == 0) goes away.

Patch 2 adds a devm_add_action() callback in hid_haptic_init() that
does all the resource teardown at unbind.  hid_haptic_destroy() just
sets ff->private = NULL so the subsequent kfree in input_ff_destroy
is harmless.  input_get_device() pins the input device for the
duration of the devres action.

Changes since v4:
  - keep devm_kzalloc, use devm_add_action (Benjamin)
  - split reorder into its own patch (Benjamin)
  - single-owner teardown -- destroy only NULLs ff->private,
    devm action owns workqueue drain + buffer frees + ref puts
  - input_get_device pins input_dev against concurrent release
  - workqueue drained before any pointer NULLs or frees
  - input_ff_destroy on devm_add_action failure
  - no hid-multitouch.c or hid-haptic.h changes

v4: https://lore.kernel.org/linux-input/20261009103333.2476105-1-qwe.aldo@gmail.com/
v3: https://lore.kernel.org/linux-input/20261009110509.2432308-1-qwe.aldo@gmail.com/
v1: https://lore.kernel.org/linux-input/20261009031207.3233206-1-qwe.aldo@gmail.com/

Aldo Ariel Panzardo (2):
  HID: haptic: reorder try_module_get/get_device before input_ff_create
  HID: multitouch: fix use-after-free of haptic data on delayed input
    release

 drivers/hid/hid-haptic.c | 87 ++++++++++++++++++++++++++++------------
 1 file changed, 62 insertions(+), 25 deletions(-)

--
2.53.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
  2026-10-16 13:55 ` [PATCH v5 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
@ 2026-10-16 13:55   ` Aldo Ariel Panzardo
  2026-10-16 13:55   ` [PATCH v5 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  2026-10-16 15:13   ` [PATCH v6 0/2] " Aldo Ariel Panzardo
  2 siblings, 0 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 13:55 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

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@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 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


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v5 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 13:55 ` [PATCH v5 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  2026-10-16 13:55   ` [PATCH v5 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
@ 2026-10-16 13:55   ` Aldo Ariel Panzardo
  2026-10-16 15:13   ` [PATCH v6 0/2] " Aldo Ariel Panzardo
  2 siblings, 0 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 13:55 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

mt_probe() allocates td->haptic with devm_kzalloc() and hid_haptic_init()
stores it in ff->private.  When the HID device is removed while an evdev
fd is still held, devres frees td->haptic at unbind but
hid_haptic_destroy() runs later from input_dev_release() and dereferences
the freed pointer.  input_ff_destroy() then double-frees it via
kfree(ff->private).

Move all resource cleanup into a devm_add_action() callback so it runs
at unbind before devres frees the struct.  hid_haptic_destroy() becomes
just ff->private = NULL, making the later kfree a no-op.  The input
device is pinned with input_get_device() to prevent concurrent release
during the devres action; the workqueue is drained first while all
buffers are still live.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 drivers/hid/hid-haptic.c | 65 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 57 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 592b44e..109b4df 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -379,32 +379,57 @@ static int hid_haptic_erase(struct input_dev *dev, int effect_id)
 
 static void hid_haptic_destroy(struct ff_device *ff)
 {
-	struct hid_haptic_device *haptic = ff->private;
-	struct hid_device *hdev = haptic->hdev;
+	/*
+	 * Resource cleanup is handled by hid_haptic_devm_release() which
+	 * runs at driver unbind.  This callback only disconnects the FF
+	 * subsystem's pointer so input_ff_destroy()'s kfree(ff->private)
+	 * becomes kfree(NULL), preventing a double-free of the
+	 * devres-managed haptic struct.
+	 */
+	ff->private = NULL;
+}
+
+static void hid_haptic_devm_release(void *data)
+{
+	struct hid_haptic_device *haptic = data;
+	struct input_dev *dev = haptic->input_dev;
 	int r;
 
-	if (hdev)
-		put_device(&hdev->dev);
+	/*
+	 * Drain pending work first -- handlers dereference ff->private
+	 * through the input_dev, so the workqueue must be idle before
+	 * we NULL that pointer or free any buffers.
+	 */
+	if (haptic->wq) {
+		destroy_workqueue(haptic->wq);
+		haptic->wq = NULL;
+	}
+
+	if (dev && dev->ff && dev->ff->private == haptic)
+		dev->ff->private = NULL;
+
+	if (haptic->hdev)
+		put_device(&haptic->hdev->dev);
 
 	kfree(haptic->stop_effect.report_buf);
 	haptic->stop_effect.report_buf = NULL;
 
 	if (haptic->effect) {
-		for (r = 0; r < ff->max_effects; r++)
+		for (r = 0; r < FF_MAX_EFFECTS; r++)
 			kfree(haptic->effect[r].report_buf);
 		kfree(haptic->effect);
 	}
 	haptic->effect = NULL;
 
-	destroy_workqueue(haptic->wq);
-	haptic->wq = NULL;
-
 	kfree(haptic->duration_map);
 	haptic->duration_map = NULL;
 
 	kfree(haptic->hid_usage_map);
 	haptic->hid_usage_map = NULL;
 
+	if (dev)
+		input_put_device(dev);
+
 	module_put(THIS_MODULE);
 }
 
@@ -419,6 +444,9 @@ 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);
@@ -511,6 +539,8 @@ int hid_haptic_init(struct hid_device *hdev,
 		goto stop_buffer_free;
 	}
 
+	flush = dev->flush;
+	event = dev->event;
 	ret = input_ff_create(dev, FF_MAX_EFFECTS);
 	if (ret) {
 		dev_err(&hdev->dev, "Failed to create ff device.\n");
@@ -525,6 +555,25 @@ int hid_haptic_init(struct hid_device *hdev,
 	ff->playback = hid_haptic_playback;
 	ff->erase = hid_haptic_erase;
 	ff->destroy = hid_haptic_destroy;
+
+	/*
+	 * Pin the input device so it cannot be released concurrently
+	 * with our devres cleanup.  hid_haptic_devm_release() drops
+	 * this reference after cleanup is complete.
+	 */
+	input_get_device(dev);
+
+	ret = devm_add_action(&hdev->dev, hid_haptic_devm_release, haptic);
+	if (ret) {
+		input_ff_destroy(dev);
+		dev->flush = flush;
+		dev->event = event;
+		input_put_device(dev);
+		put_device(&hdev->dev);
+		module_put(THIS_MODULE);
+		goto stop_buffer_free;
+	}
+
 	return 0;
 
 stop_buffer_free:
-- 
2.53.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v6 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 13:55 ` [PATCH v5 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  2026-10-16 13:55   ` [PATCH v5 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
  2026-10-16 13:55   ` [PATCH v5 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
@ 2026-10-16 15:13   ` Aldo Ariel Panzardo
  2026-10-16 15:13     ` [PATCH v6 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
                       ` (2 more replies)
  2 siblings, 3 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 15:13 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

v6 fixes issues found by Sashiko on v5.

Patch 1 is unchanged -- reorders try_module_get()/get_device() before
input_ff_create().

Patch 2 keeps the devm_add_action() design.  Changes since v5:
  - module_put moved to hid_haptic_destroy so the module stays loaded
    until the FF subsystem is done with the callback; a second
    __module_get covers hid_haptic_devm_release itself
  - guard against double-init (return 0 when haptic->wq is set)
  - NULL haptic->hdev and haptic->input_dev after put in devm_release
  - restore dev->flush/event after input_ff_destroy on devm_add_action
    failure

v5: https://lore.kernel.org/linux-input/20261016135516.2957381-1-qwe.aldo@gmail.com/
v4: https://lore.kernel.org/linux-input/20261009103333.2476105-1-qwe.aldo@gmail.com/
v1: https://lore.kernel.org/linux-input/20261009031207.3233206-1-qwe.aldo@gmail.com/

Aldo Ariel Panzardo (2):
  HID: haptic: reorder try_module_get/get_device before input_ff_create
  HID: multitouch: fix use-after-free of haptic data on delayed input
    release

 drivers/hid/hid-haptic.c | 93 ++++++++++++++++++++++++++++++++++------
 1 file changed, 80 insertions(+), 13 deletions(-)

--
2.53.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v6 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
  2026-10-16 15:13   ` [PATCH v6 0/2] " Aldo Ariel Panzardo
@ 2026-10-16 15:13     ` Aldo Ariel Panzardo
  2026-10-16 15:13     ` [PATCH v6 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  2026-10-16 16:33     ` [PATCH v7 0/2] " Aldo Ariel Panzardo
  2 siblings, 0 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 15:13 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

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@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 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


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v6 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 15:13   ` [PATCH v6 0/2] " Aldo Ariel Panzardo
  2026-10-16 15:13     ` [PATCH v6 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
@ 2026-10-16 15:13     ` Aldo Ariel Panzardo
  2026-10-16 16:33     ` [PATCH v7 0/2] " Aldo Ariel Panzardo
  2 siblings, 0 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 15:13 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

mt_probe() allocates td->haptic with devm_kzalloc() and hid_haptic_init()
stores it in ff->private.  When the HID device is removed while an evdev
fd is still held, devres frees td->haptic at unbind but
hid_haptic_destroy() runs later from input_dev_release() and dereferences
the freed pointer.  input_ff_destroy() then double-frees it via
kfree(ff->private).

Move all resource cleanup into a devm_add_action() callback so it runs
at unbind before devres frees the struct.  hid_haptic_destroy() becomes
ff->private = NULL plus module_put() -- keeping the module loaded until
the FF subsystem is done with the callback.  The input device is pinned
with input_get_device() to prevent concurrent release during the devres
action; the workqueue is drained first while all buffers are still live.

Guard against double-init when multiple touchpad collections trigger
hid_haptic_init() for the same haptic struct.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 drivers/hid/hid-haptic.c | 74 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 66 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 592b44e..6d72d9c 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -379,32 +379,61 @@ static int hid_haptic_erase(struct input_dev *dev, int effect_id)
 
 static void hid_haptic_destroy(struct ff_device *ff)
 {
-	struct hid_haptic_device *haptic = ff->private;
-	struct hid_device *hdev = haptic->hdev;
+	/*
+	 * Resource cleanup is handled by hid_haptic_devm_release() at
+	 * driver unbind.  Disconnect the FF pointer so input_ff_destroy()'s
+	 * kfree(ff->private) becomes kfree(NULL).  Drop the module
+	 * reference last -- it must outlive this callback.
+	 */
+	ff->private = NULL;
+	module_put(THIS_MODULE);
+}
+
+static void hid_haptic_devm_release(void *data)
+{
+	struct hid_haptic_device *haptic = data;
+	struct input_dev *dev = haptic->input_dev;
 	int r;
 
-	if (hdev)
-		put_device(&hdev->dev);
+	/*
+	 * Drain pending work first -- handlers dereference ff->private
+	 * through the input_dev, so the workqueue must be idle before
+	 * we NULL that pointer or free any buffers.
+	 */
+	if (haptic->wq) {
+		destroy_workqueue(haptic->wq);
+		haptic->wq = NULL;
+	}
+
+	if (dev && dev->ff && dev->ff->private == haptic)
+		dev->ff->private = NULL;
+
+	if (haptic->hdev) {
+		put_device(&haptic->hdev->dev);
+		haptic->hdev = NULL;
+	}
 
 	kfree(haptic->stop_effect.report_buf);
 	haptic->stop_effect.report_buf = NULL;
 
 	if (haptic->effect) {
-		for (r = 0; r < ff->max_effects; r++)
+		for (r = 0; r < FF_MAX_EFFECTS; r++)
 			kfree(haptic->effect[r].report_buf);
 		kfree(haptic->effect);
 	}
 	haptic->effect = NULL;
 
-	destroy_workqueue(haptic->wq);
-	haptic->wq = NULL;
-
 	kfree(haptic->duration_map);
 	haptic->duration_map = NULL;
 
 	kfree(haptic->hid_usage_map);
 	haptic->hid_usage_map = NULL;
 
+	if (dev) {
+		input_put_device(dev);
+		haptic->input_dev = NULL;
+	}
+
 	module_put(THIS_MODULE);
 }
 
@@ -414,12 +443,17 @@ int hid_haptic_init(struct hid_device *hdev,
 {
 	struct ff_device *ff;
 	int ret = 0, r;
+	int (*saved_flush)(struct input_dev *, struct file *);
+	int (*saved_event)(struct input_dev *, unsigned int, unsigned int, int);
 	struct ff_haptic_effect stop_effect = {
 		.hid_usage = HID_HP_WAVEFORMSTOP & HID_USAGE,
 	};
 	const char *prefix = "hid-haptic";
 	char *name;
 
+	if (haptic->wq)
+		return 0;
+
 	haptic->hdev = hdev;
 	haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
 	haptic->max_duration_id = max(2u, haptic->max_duration_id);
@@ -511,6 +545,8 @@ int hid_haptic_init(struct hid_device *hdev,
 		goto stop_buffer_free;
 	}
 
+	saved_flush = dev->flush;
+	saved_event = dev->event;
 	ret = input_ff_create(dev, FF_MAX_EFFECTS);
 	if (ret) {
 		dev_err(&hdev->dev, "Failed to create ff device.\n");
@@ -525,6 +561,28 @@ int hid_haptic_init(struct hid_device *hdev,
 	ff->playback = hid_haptic_playback;
 	ff->erase = hid_haptic_erase;
 	ff->destroy = hid_haptic_destroy;
+
+	/*
+	 * Pin the input device so it cannot be released concurrently
+	 * with our devres cleanup, and take a second module reference
+	 * so the module stays loaded while hid_haptic_devm_release()
+	 * executes (the first ref is dropped by hid_haptic_destroy()
+	 * which may run inside input_put_device() below).
+	 */
+	input_get_device(dev);
+	__module_get(THIS_MODULE);
+
+	ret = devm_add_action(&hdev->dev, hid_haptic_devm_release, haptic);
+	if (ret) {
+		module_put(THIS_MODULE);
+		input_ff_destroy(dev);
+		dev->flush = saved_flush;
+		dev->event = saved_event;
+		input_put_device(dev);
+		put_device(&hdev->dev);
+		goto stop_buffer_free;
+	}
+
 	return 0;
 
 stop_buffer_free:
-- 
2.53.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v7 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 15:13   ` [PATCH v6 0/2] " Aldo Ariel Panzardo
  2026-10-16 15:13     ` [PATCH v6 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
  2026-10-16 15:13     ` [PATCH v6 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
@ 2026-10-16 16:33     ` Aldo Ariel Panzardo
  2026-10-16 16:33       ` [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
                         ` (2 more replies)
  2 siblings, 3 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 16:33 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

v7 fixes issues found by Sashiko on v5 and v6.

Patch 1 now moves input_set_capability(EV_FF) after input_ff_create()
so the capability is not advertised when FF setup fails -- the caller
masks the error and EVIOCGEFFECTS would deref a NULL dev->ff.

Patch 2 keeps the devm_add_action() design.  Changes since v5:
  - module_put in hid_haptic_destroy (not devm_release) so the module
    stays loaded until FF is done; __module_get for devm_release itself
  - guard against double-init (return 0 when haptic->wq is set)
  - NULL haptic->hdev and haptic->input_dev after put in devm_release
  - restore dev->flush/event on devm_add_action failure

v6: https://lore.kernel.org/linux-input/20261016151343.3120300-1-qwe.aldo@gmail.com/
v5: https://lore.kernel.org/linux-input/20261016135516.2957381-1-qwe.aldo@gmail.com/
v4: https://lore.kernel.org/linux-input/20261009103333.2476105-1-qwe.aldo@gmail.com/
v1: https://lore.kernel.org/linux-input/20261009031207.3233206-1-qwe.aldo@gmail.com/

Aldo Ariel Panzardo (2):
  HID: haptic: reorder try_module_get/get_device before input_ff_create
  HID: multitouch: fix use-after-free of haptic data on delayed input
    release

 drivers/hid/hid-haptic.c | 105 +++++++++++++++++++++++++++++++++------
 1 file changed, 79 insertions(+), 26 deletions(-)

--
2.53.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
  2026-10-16 16:33     ` [PATCH v7 0/2] " Aldo Ariel Panzardo
@ 2026-10-16 16:33       ` Aldo Ariel Panzardo
  2026-10-16 18:16         ` Dmitry Torokhov
  2026-10-16 16:33       ` [PATCH v7 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  2026-10-16 17:30       ` [PATCH v8 0/2] " Aldo Ariel Panzardo
  2 siblings, 1 reply; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 16:33 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

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.

Also move input_set_capability(dev, EV_FF, FF_HAPTIC) after
input_ff_create() so the capability is not advertised when FF setup
fails -- the caller masks the error and the input device may still
be registered, where EVIOCGEFFECTS would dereference a NULL dev->ff.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 drivers/hid/hid-haptic.c | 35 +++++++++++++++--------------------
 1 file changed, 15 insertions(+), 20 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 8760eeb..9753bbf 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);
@@ -499,39 +497,36 @@ int hid_haptic_init(struct hid_device *hdev,
 	fill_effect_buf(haptic, &stop_effect, &haptic->stop_effect,
 			HID_HAPTIC_ORDINAL_WAVEFORMSTOP);
 
-	input_set_capability(dev, EV_FF, FF_HAPTIC);
+	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;
+	}
 
-	flush = dev->flush;
-	event = dev->event;
 	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;
 	}
 
+	input_set_capability(dev, EV_FF, FF_HAPTIC);
+
 	ff = dev->ff;
 	ff->private = haptic;
 	ff->upload = hid_haptic_upload_effect;
 	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


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v7 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 16:33     ` [PATCH v7 0/2] " Aldo Ariel Panzardo
  2026-10-16 16:33       ` [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
@ 2026-10-16 16:33       ` Aldo Ariel Panzardo
  2026-10-16 17:30       ` [PATCH v8 0/2] " Aldo Ariel Panzardo
  2 siblings, 0 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 16:33 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

mt_probe() allocates td->haptic with devm_kzalloc() and hid_haptic_init()
stores it in ff->private.  When the HID device is removed while an evdev
fd is still held, devres frees td->haptic at unbind but
hid_haptic_destroy() runs later from input_dev_release() and dereferences
the freed pointer.  input_ff_destroy() then double-frees it via
kfree(ff->private).

Move all resource cleanup into a devm_add_action() callback so it runs
at unbind before devres frees the struct.  hid_haptic_destroy() becomes
ff->private = NULL plus module_put() -- keeping the module loaded until
the FF subsystem is done with the callback.  A second __module_get()
covers hid_haptic_devm_release() itself, dropped after input_put_device().
The input device is pinned with input_get_device() to prevent concurrent
release during the devres action; the workqueue is drained first while
all buffers are still live.

Guard against double-init when multiple touchpad collections trigger
hid_haptic_init() for the same haptic struct.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 drivers/hid/hid-haptic.c | 74 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 66 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 9753bbf..c7fafb3 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -379,32 +379,61 @@ static int hid_haptic_erase(struct input_dev *dev, int effect_id)
 
 static void hid_haptic_destroy(struct ff_device *ff)
 {
-	struct hid_haptic_device *haptic = ff->private;
-	struct hid_device *hdev = haptic->hdev;
+	/*
+	 * Resource cleanup is handled by hid_haptic_devm_release() at
+	 * driver unbind.  Disconnect the FF pointer so input_ff_destroy()'s
+	 * kfree(ff->private) becomes kfree(NULL).  Drop the module
+	 * reference last -- it must outlive this callback.
+	 */
+	ff->private = NULL;
+	module_put(THIS_MODULE);
+}
+
+static void hid_haptic_devm_release(void *data)
+{
+	struct hid_haptic_device *haptic = data;
+	struct input_dev *dev = haptic->input_dev;
 	int r;
 
-	if (hdev)
-		put_device(&hdev->dev);
+	/*
+	 * Drain pending work first -- handlers dereference ff->private
+	 * through the input_dev, so the workqueue must be idle before
+	 * we NULL that pointer or free any buffers.
+	 */
+	if (haptic->wq) {
+		destroy_workqueue(haptic->wq);
+		haptic->wq = NULL;
+	}
+
+	if (dev && dev->ff && dev->ff->private == haptic)
+		dev->ff->private = NULL;
+
+	if (haptic->hdev) {
+		put_device(&haptic->hdev->dev);
+		haptic->hdev = NULL;
+	}
 
 	kfree(haptic->stop_effect.report_buf);
 	haptic->stop_effect.report_buf = NULL;
 
 	if (haptic->effect) {
-		for (r = 0; r < ff->max_effects; r++)
+		for (r = 0; r < FF_MAX_EFFECTS; r++)
 			kfree(haptic->effect[r].report_buf);
 		kfree(haptic->effect);
 	}
 	haptic->effect = NULL;
 
-	destroy_workqueue(haptic->wq);
-	haptic->wq = NULL;
-
 	kfree(haptic->duration_map);
 	haptic->duration_map = NULL;
 
 	kfree(haptic->hid_usage_map);
 	haptic->hid_usage_map = NULL;
 
+	if (dev) {
+		input_put_device(dev);
+		haptic->input_dev = NULL;
+	}
+
 	module_put(THIS_MODULE);
 }
 
@@ -419,6 +448,11 @@ int hid_haptic_init(struct hid_device *hdev,
 	};
 	const char *prefix = "hid-haptic";
 	char *name;
+	int (*saved_flush)(struct input_dev *, struct file *);
+	int (*saved_event)(struct input_dev *, unsigned int, unsigned int, int);
+
+	if (haptic->wq)
+		return 0;
 
 	haptic->hdev = hdev;
 	haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
@@ -509,6 +543,8 @@ int hid_haptic_init(struct hid_device *hdev,
 		goto stop_buffer_free;
 	}
 
+	saved_flush = dev->flush;
+	saved_event = dev->event;
 	ret = input_ff_create(dev, FF_MAX_EFFECTS);
 	if (ret) {
 		dev_err(&hdev->dev, "Failed to create ff device.\n");
@@ -525,6 +561,28 @@ int hid_haptic_init(struct hid_device *hdev,
 	ff->playback = hid_haptic_playback;
 	ff->erase = hid_haptic_erase;
 	ff->destroy = hid_haptic_destroy;
+
+	/*
+	 * Pin the input device so it cannot be released concurrently
+	 * with our devres cleanup, and take a second module reference
+	 * so the module stays loaded while hid_haptic_devm_release()
+	 * executes (the first ref is dropped by hid_haptic_destroy()
+	 * which may run inside input_put_device() below).
+	 */
+	input_get_device(dev);
+	__module_get(THIS_MODULE);
+
+	ret = devm_add_action(&hdev->dev, hid_haptic_devm_release, haptic);
+	if (ret) {
+		module_put(THIS_MODULE);
+		input_ff_destroy(dev);
+		dev->flush = saved_flush;
+		dev->event = saved_event;
+		input_put_device(dev);
+		put_device(&hdev->dev);
+		goto stop_buffer_free;
+	}
+
 	return 0;
 
 stop_buffer_free:
-- 
2.53.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v8 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 16:33     ` [PATCH v7 0/2] " Aldo Ariel Panzardo
  2026-10-16 16:33       ` [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
  2026-10-16 16:33       ` [PATCH v7 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
@ 2026-10-16 17:30       ` Aldo Ariel Panzardo
  2026-10-16 17:30         ` [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
  2026-10-16 17:30         ` [PATCH v8 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  2 siblings, 2 replies; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 17:30 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

v8 fixes issues found by Sashiko on v5-v7.

Patch 1 keeps input_set_capability(EV_FF) before input_ff_create()
(ff->ffbit needs the bit), but clears both bits on failure via a new
ff_cap_clear label so a masked error from the caller does not leave
EV_FF set with a NULL dev->ff.

Patch 2 keeps the devm_add_action() design.  Changes since v5:
  - module_put in hid_haptic_destroy (not devm_release) so the module
    stays loaded until FF is done; __module_get for devm_release itself
  - guard against double-init (return 0 when haptic->wq is set)
  - NULL haptic->hdev and haptic->input_dev after put in devm_release
  - restore dev->flush/event on devm_add_action failure

v7: https://lore.kernel.org/linux-input/20261016163349.3293666-1-qwe.aldo@gmail.com/
v5: https://lore.kernel.org/linux-input/20261016135516.2957381-1-qwe.aldo@gmail.com/
v4: https://lore.kernel.org/linux-input/20261009103333.2476105-1-qwe.aldo@gmail.com/
v1: https://lore.kernel.org/linux-input/20261009031207.3233206-1-qwe.aldo@gmail.com/

Aldo Ariel Panzardo (2):
  HID: haptic: reorder try_module_get/get_device before input_ff_create
  HID: multitouch: fix use-after-free of haptic data on delayed input
    release

 drivers/hid/hid-haptic.c | 108 +++++++++++++++++++++++++++++++++------
 1 file changed, 82 insertions(+), 26 deletions(-)

--
2.53.0

^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
  2026-10-16 17:30       ` [PATCH v8 0/2] " Aldo Ariel Panzardo
@ 2026-10-16 17:30         ` Aldo Ariel Panzardo
  2026-10-17 11:49           ` kernel test robot
  2026-10-16 17:30         ` [PATCH v8 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
  1 sibling, 1 reply; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 17:30 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

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.

Clear the EV_FF and FF_HAPTIC capability bits on failure so a masked
error from the caller does not leave the input device advertising FF
support without a dev->ff -- EVIOCGEFFECTS would NULL-deref otherwise.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 drivers/hid/hid-haptic.c | 38 ++++++++++++++++++--------------------
 1 file changed, 18 insertions(+), 20 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index 8760eeb..b8aa4bf 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,12 +499,24 @@ 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 ff_cap_clear;
+	}
+	if (!get_device(&hdev->dev)) {
+		dev_err(&hdev->dev, "Failed to get hdev device.\n");
+		ret = -ENODEV;
+		module_put(THIS_MODULE);
+		goto ff_cap_clear;
+	}
+
 	ret = input_ff_create(dev, FF_MAX_EFFECTS);
 	if (ret) {
 		dev_err(&hdev->dev, "Failed to create ff device.\n");
-		goto stop_buffer_free;
+		put_device(&hdev->dev);
+		module_put(THIS_MODULE);
+		goto ff_cap_clear;
 	}
 
 	ff = dev->ff;
@@ -515,23 +525,11 @@ 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;
+ff_cap_clear:
+	__clear_bit(FF_HAPTIC, dev->ffbit);
+	__clear_bit(EV_FF, dev->evbit);
 stop_buffer_free:
 	kfree(haptic->stop_effect.report_buf);
 	haptic->stop_effect.report_buf = NULL;
-- 
2.53.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH v8 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 17:30       ` [PATCH v8 0/2] " Aldo Ariel Panzardo
  2026-10-16 17:30         ` [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
@ 2026-10-16 17:30         ` Aldo Ariel Panzardo
  2026-10-16 18:27           ` Dmitry Torokhov
  1 sibling, 1 reply; 15+ messages in thread
From: Aldo Ariel Panzardo @ 2026-10-16 17:30 UTC (permalink / raw)
  To: jikos, bentiss
  Cc: dmitry.torokhov, linux-input, linux-kernel, stable, Aldo Ariel Panzardo

mt_probe() allocates td->haptic with devm_kzalloc() and hid_haptic_init()
stores it in ff->private.  When the HID device is removed while an evdev
fd is still held, devres frees td->haptic at unbind but
hid_haptic_destroy() runs later from input_dev_release() and dereferences
the freed pointer.  input_ff_destroy() then double-frees it via
kfree(ff->private).

Move all resource cleanup into a devm_add_action() callback so it runs
at unbind before devres frees the struct.  hid_haptic_destroy() becomes
ff->private = NULL plus module_put() -- keeping the module loaded until
the FF subsystem is done with the callback.  A second __module_get()
covers hid_haptic_devm_release() itself, dropped after input_put_device().
The input device is pinned with input_get_device() to prevent concurrent
release during the devres action; the workqueue is drained first while
all buffers are still live.

Guard against double-init when multiple touchpad collections trigger
hid_haptic_init() for the same haptic struct.

Fixes: 8d0bf7908b5a ("HID: multitouch: add haptic multitouch support")
Cc: stable@vger.kernel.org
Signed-off-by: Aldo Ariel Panzardo <qwe.aldo@gmail.com>
---
 drivers/hid/hid-haptic.c | 74 +++++++++++++++++++++++++++++++++++-----
 1 file changed, 66 insertions(+), 8 deletions(-)

diff --git a/drivers/hid/hid-haptic.c b/drivers/hid/hid-haptic.c
index b8aa4bf..e4e9bb9 100644
--- a/drivers/hid/hid-haptic.c
+++ b/drivers/hid/hid-haptic.c
@@ -379,32 +379,61 @@ static int hid_haptic_erase(struct input_dev *dev, int effect_id)
 
 static void hid_haptic_destroy(struct ff_device *ff)
 {
-	struct hid_haptic_device *haptic = ff->private;
-	struct hid_device *hdev = haptic->hdev;
+	/*
+	 * Resource cleanup is handled by hid_haptic_devm_release() at
+	 * driver unbind.  Disconnect the FF pointer so input_ff_destroy()'s
+	 * kfree(ff->private) becomes kfree(NULL).  Drop the module
+	 * reference last -- it must outlive this callback.
+	 */
+	ff->private = NULL;
+	module_put(THIS_MODULE);
+}
+
+static void hid_haptic_devm_release(void *data)
+{
+	struct hid_haptic_device *haptic = data;
+	struct input_dev *dev = haptic->input_dev;
 	int r;
 
-	if (hdev)
-		put_device(&hdev->dev);
+	/*
+	 * Drain pending work first -- handlers dereference ff->private
+	 * through the input_dev, so the workqueue must be idle before
+	 * we NULL that pointer or free any buffers.
+	 */
+	if (haptic->wq) {
+		destroy_workqueue(haptic->wq);
+		haptic->wq = NULL;
+	}
+
+	if (dev && dev->ff && dev->ff->private == haptic)
+		dev->ff->private = NULL;
+
+	if (haptic->hdev) {
+		put_device(&haptic->hdev->dev);
+		haptic->hdev = NULL;
+	}
 
 	kfree(haptic->stop_effect.report_buf);
 	haptic->stop_effect.report_buf = NULL;
 
 	if (haptic->effect) {
-		for (r = 0; r < ff->max_effects; r++)
+		for (r = 0; r < FF_MAX_EFFECTS; r++)
 			kfree(haptic->effect[r].report_buf);
 		kfree(haptic->effect);
 	}
 	haptic->effect = NULL;
 
-	destroy_workqueue(haptic->wq);
-	haptic->wq = NULL;
-
 	kfree(haptic->duration_map);
 	haptic->duration_map = NULL;
 
 	kfree(haptic->hid_usage_map);
 	haptic->hid_usage_map = NULL;
 
+	if (dev) {
+		input_put_device(dev);
+		haptic->input_dev = NULL;
+	}
+
 	module_put(THIS_MODULE);
 }
 
@@ -419,6 +448,11 @@ int hid_haptic_init(struct hid_device *hdev,
 	};
 	const char *prefix = "hid-haptic";
 	char *name;
+	int (*saved_flush)(struct input_dev *, struct file *);
+	int (*saved_event)(struct input_dev *, unsigned int, unsigned int, int);
+
+	if (haptic->wq)
+		return 0;
 
 	haptic->hdev = hdev;
 	haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
@@ -511,6 +545,8 @@ int hid_haptic_init(struct hid_device *hdev,
 		goto ff_cap_clear;
 	}
 
+	saved_flush = dev->flush;
+	saved_event = dev->event;
 	ret = input_ff_create(dev, FF_MAX_EFFECTS);
 	if (ret) {
 		dev_err(&hdev->dev, "Failed to create ff device.\n");
@@ -525,6 +561,28 @@ int hid_haptic_init(struct hid_device *hdev,
 	ff->playback = hid_haptic_playback;
 	ff->erase = hid_haptic_erase;
 	ff->destroy = hid_haptic_destroy;
+
+	/*
+	 * Pin the input device so it cannot be released concurrently
+	 * with our devres cleanup, and take a second module reference
+	 * so the module stays loaded while hid_haptic_devm_release()
+	 * executes (the first ref is dropped by hid_haptic_destroy()
+	 * which may run inside input_put_device() below).
+	 */
+	input_get_device(dev);
+	__module_get(THIS_MODULE);
+
+	ret = devm_add_action(&hdev->dev, hid_haptic_devm_release, haptic);
+	if (ret) {
+		module_put(THIS_MODULE);
+		input_ff_destroy(dev);
+		dev->flush = saved_flush;
+		dev->event = saved_event;
+		input_put_device(dev);
+		put_device(&hdev->dev);
+		goto ff_cap_clear;
+	}
+
 	return 0;
 
 ff_cap_clear:
-- 
2.53.0


^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
  2026-10-16 16:33       ` [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
@ 2026-10-16 18:16         ` Dmitry Torokhov
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Torokhov @ 2026-10-16 18:16 UTC (permalink / raw)
  To: Aldo Ariel Panzardo; +Cc: jikos, bentiss, linux-input, linux-kernel, stable

Hi Aldo,

On Fri, Oct 16, 2026 at 01:33:48PM -0300, Aldo Ariel Panzardo wrote:
> 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.

How about we simply stop pretending that these can fail? I.e. replace
try_module_get() with __module_get() 

As far as get_device() it cannot fail and is redundant:

- get_device(&hdev->dev) only returns NULL if its argument is NULL,
  which is impossible here since hdev was already dereferenced
  throughout hid_haptic_init()

- In hidinput_allocate(), input_dev->dev.parent is set to &hdev->dev.
  The driver core will already hold a reference to &hdev->dev
  (dev->parent) that will only released in device_release() after
  input_dev_release() -> input_ff_destroy() -> hid_haptic_destroy()
  finishes.

Additionally I think we should simply fail probe if hid_haptic_init()
fails instead of trying to limp along without it.

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release
  2026-10-16 17:30         ` [PATCH v8 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
@ 2026-10-16 18:27           ` Dmitry Torokhov
  0 siblings, 0 replies; 15+ messages in thread
From: Dmitry Torokhov @ 2026-10-16 18:27 UTC (permalink / raw)
  To: Aldo Ariel Panzardo; +Cc: jikos, bentiss, linux-input, linux-kernel, stable

On Fri, Oct 16, 2026 at 02:30:56PM -0300, Aldo Ariel Panzardo wrote:
> mt_probe() allocates td->haptic with devm_kzalloc() and hid_haptic_init()
> stores it in ff->private.  When the HID device is removed while an evdev
> fd is still held, devres frees td->haptic at unbind but
> hid_haptic_destroy() runs later from input_dev_release() and dereferences
> the freed pointer.  input_ff_destroy() then double-frees it via
> kfree(ff->private).

Right, so that is the root of the problem. We should not be allocating
memory assigned to ff->private with devm as its lifetime is not directly
tied to the time when device is bound to a driver.

Your initial approach was correct one. 

Thanks.

-- 
Dmitry

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
  2026-10-16 17:30         ` [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
@ 2026-10-17 11:49           ` kernel test robot
  0 siblings, 0 replies; 15+ messages in thread
From: kernel test robot @ 2026-10-17 11:49 UTC (permalink / raw)
  To: Aldo Ariel Panzardo, jikos, bentiss
  Cc: oe-kbuild-all, dmitry.torokhov, linux-input, linux-kernel,
	stable, Aldo Ariel Panzardo

Hi Aldo,

kernel test robot noticed the following build warnings:

[auto build test WARNING on hid/for-next]
[also build test WARNING on linus/master v7.3-rc7 next-20261016]
[If your patch is applied to the wrong git tree, kindly drop us a note.
And when submitting patch, we suggest to use '--base' as documented in
https://git-scm.com/docs/git-format-patch#_base_tree_information]

url:    https://github.com/intel-lab-lkp/linux/commits/Aldo-Ariel-Panzardo/HID-multitouch-fix-use-after-free-of-haptic-data-on-delayed-input-release/20261016-143056
base:   https://git.kernel.org/pub/scm/linux/kernel/git/hid/hid.git for-next
patch link:    https://lore.kernel.org/r/20261016173056.3397211-2-qwe.aldo%40gmail.com
patch subject: [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create
config: arc-randconfig-1001-20261017 (https://download.01.org/0day-ci/archive/20261017/202610171937.9UEsJzAu-lkp@intel.com/config)
compiler: arc-linux-gcc (GCC) 10.5.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20261017/202610171937.9UEsJzAu-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202610171937.9UEsJzAu-lkp@intel.com/

All warnings (new ones prefixed by >>):

   drivers/hid/hid-haptic.c: In function 'hid_haptic_init':
>> drivers/hid/hid-haptic.c:533:1: warning: label 'stop_buffer_free' defined but not used [-Wunused-label]
     533 | stop_buffer_free:
         | ^~~~~~~~~~~~~~~~


vim +/stop_buffer_free +533 drivers/hid/hid-haptic.c

344ff358495706a Angela Czubak       2025-08-18  410  
344ff358495706a Angela Czubak       2025-08-18  411  int hid_haptic_init(struct hid_device *hdev,
7939f787f450d93 Dmitry Torokhov     2026-08-03  412  		    struct hid_haptic_device *haptic,
7939f787f450d93 Dmitry Torokhov     2026-08-03  413  		    struct input_dev *dev)
344ff358495706a Angela Czubak       2025-08-18  414  {
344ff358495706a Angela Czubak       2025-08-18  415  	struct ff_device *ff;
344ff358495706a Angela Czubak       2025-08-18  416  	int ret = 0, r;
344ff358495706a Angela Czubak       2025-08-18  417  	struct ff_haptic_effect stop_effect = {
344ff358495706a Angela Czubak       2025-08-18  418  		.hid_usage = HID_HP_WAVEFORMSTOP & HID_USAGE,
344ff358495706a Angela Czubak       2025-08-18  419  	};
344ff358495706a Angela Czubak       2025-08-18  420  	const char *prefix = "hid-haptic";
344ff358495706a Angela Czubak       2025-08-18  421  	char *name;
344ff358495706a Angela Czubak       2025-08-18  422  
344ff358495706a Angela Czubak       2025-08-18  423  	haptic->hdev = hdev;
344ff358495706a Angela Czubak       2025-08-18  424  	haptic->max_waveform_id = max(2u, haptic->max_waveform_id);
344ff358495706a Angela Czubak       2025-08-18  425  	haptic->max_duration_id = max(2u, haptic->max_duration_id);
344ff358495706a Angela Czubak       2025-08-18  426  
344ff358495706a Angela Czubak       2025-08-18  427  	haptic->hid_usage_map = kcalloc(haptic->max_waveform_id + 1,
344ff358495706a Angela Czubak       2025-08-18  428  					sizeof(u16), GFP_KERNEL);
344ff358495706a Angela Czubak       2025-08-18  429  	if (!haptic->hid_usage_map) {
344ff358495706a Angela Czubak       2025-08-18  430  		ret = -ENOMEM;
344ff358495706a Angela Czubak       2025-08-18  431  		goto exit;
344ff358495706a Angela Czubak       2025-08-18  432  	}
344ff358495706a Angela Czubak       2025-08-18  433  	haptic->duration_map = kcalloc(haptic->max_duration_id + 1,
344ff358495706a Angela Czubak       2025-08-18  434  				       sizeof(u32), GFP_KERNEL);
344ff358495706a Angela Czubak       2025-08-18  435  	if (!haptic->duration_map) {
344ff358495706a Angela Czubak       2025-08-18  436  		ret = -ENOMEM;
344ff358495706a Angela Czubak       2025-08-18  437  		goto usage_map;
344ff358495706a Angela Czubak       2025-08-18  438  	}
344ff358495706a Angela Czubak       2025-08-18  439  
344ff358495706a Angela Czubak       2025-08-18  440  	if (haptic->max_waveform_id != haptic->max_duration_id)
344ff358495706a Angela Czubak       2025-08-18  441  		dev_warn(&hdev->dev,
344ff358495706a Angela Czubak       2025-08-18  442  			 "Haptic duration and waveform lists have different max id (%u and %u).\n",
344ff358495706a Angela Czubak       2025-08-18  443  			 haptic->max_duration_id, haptic->max_waveform_id);
344ff358495706a Angela Czubak       2025-08-18  444  
344ff358495706a Angela Czubak       2025-08-18  445  	haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMNONE] =
344ff358495706a Angela Czubak       2025-08-18  446  		HID_HP_WAVEFORMNONE & HID_USAGE;
344ff358495706a Angela Czubak       2025-08-18  447  	haptic->hid_usage_map[HID_HAPTIC_ORDINAL_WAVEFORMSTOP] =
344ff358495706a Angela Czubak       2025-08-18  448  		HID_HP_WAVEFORMSTOP & HID_USAGE;
344ff358495706a Angela Czubak       2025-08-18  449  
ff66b8eebbab371 Angela Czubak       2025-08-18  450  	mutex_init(&haptic->auto_trigger_mutex);
344ff358495706a Angela Czubak       2025-08-18  451  	for (r = 0; r < haptic->auto_trigger_report->maxfield; r++)
344ff358495706a Angela Czubak       2025-08-18  452  		parse_auto_trigger_field(haptic, haptic->auto_trigger_report->field[r]);
344ff358495706a Angela Czubak       2025-08-18  453  
344ff358495706a Angela Czubak       2025-08-18  454  	haptic->input_dev = dev;
344ff358495706a Angela Czubak       2025-08-18  455  	haptic->manual_trigger_report_len =
344ff358495706a Angela Czubak       2025-08-18  456  		hid_report_len(haptic->manual_trigger_report);
344ff358495706a Angela Czubak       2025-08-18  457  	mutex_init(&haptic->manual_trigger_mutex);
344ff358495706a Angela Czubak       2025-08-18  458  	name = kmalloc(strlen(prefix) + strlen(hdev->name) + 2, GFP_KERNEL);
344ff358495706a Angela Czubak       2025-08-18  459  	if (name) {
344ff358495706a Angela Czubak       2025-08-18  460  		sprintf(name, "%s %s", prefix, hdev->name);
344ff358495706a Angela Czubak       2025-08-18  461  		haptic->wq = create_singlethread_workqueue(name);
344ff358495706a Angela Czubak       2025-08-18  462  		kfree(name);
344ff358495706a Angela Czubak       2025-08-18  463  	}
344ff358495706a Angela Czubak       2025-08-18  464  	if (!haptic->wq) {
344ff358495706a Angela Czubak       2025-08-18  465  		ret = -ENOMEM;
344ff358495706a Angela Czubak       2025-08-18  466  		goto duration_map;
344ff358495706a Angela Czubak       2025-08-18  467  	}
32a92f8c8932698 Linus Torvalds      2026-02-21  468  	haptic->effect = kzalloc_objs(struct hid_haptic_effect, FF_MAX_EFFECTS);
344ff358495706a Angela Czubak       2025-08-18  469  	if (!haptic->effect) {
344ff358495706a Angela Czubak       2025-08-18  470  		ret = -ENOMEM;
344ff358495706a Angela Czubak       2025-08-18  471  		goto output_queue;
344ff358495706a Angela Czubak       2025-08-18  472  	}
344ff358495706a Angela Czubak       2025-08-18  473  	for (r = 0; r < FF_MAX_EFFECTS; r++) {
344ff358495706a Angela Czubak       2025-08-18  474  		haptic->effect[r].report_buf =
344ff358495706a Angela Czubak       2025-08-18  475  			hid_alloc_report_buf(haptic->manual_trigger_report,
344ff358495706a Angela Czubak       2025-08-18  476  					     GFP_KERNEL);
344ff358495706a Angela Czubak       2025-08-18  477  		if (!haptic->effect[r].report_buf) {
344ff358495706a Angela Czubak       2025-08-18  478  			dev_err(&hdev->dev,
344ff358495706a Angela Czubak       2025-08-18  479  				"Failed to allocate a buffer for an effect.\n");
344ff358495706a Angela Czubak       2025-08-18  480  			ret = -ENOMEM;
344ff358495706a Angela Czubak       2025-08-18  481  			goto buffer_free;
344ff358495706a Angela Czubak       2025-08-18  482  		}
344ff358495706a Angela Czubak       2025-08-18  483  		haptic->effect[r].input_dev = dev;
344ff358495706a Angela Czubak       2025-08-18  484  		INIT_WORK(&haptic->effect[r].work, haptic_work_handler);
344ff358495706a Angela Czubak       2025-08-18  485  	}
344ff358495706a Angela Czubak       2025-08-18  486  	haptic->stop_effect.report_buf =
344ff358495706a Angela Czubak       2025-08-18  487  		hid_alloc_report_buf(haptic->manual_trigger_report,
344ff358495706a Angela Czubak       2025-08-18  488  				     GFP_KERNEL);
344ff358495706a Angela Czubak       2025-08-18  489  	if (!haptic->stop_effect.report_buf) {
344ff358495706a Angela Czubak       2025-08-18  490  		dev_err(&hdev->dev,
344ff358495706a Angela Czubak       2025-08-18  491  			"Failed to allocate a buffer for stop effect.\n");
344ff358495706a Angela Czubak       2025-08-18  492  		ret = -ENOMEM;
344ff358495706a Angela Czubak       2025-08-18  493  		goto buffer_free;
344ff358495706a Angela Czubak       2025-08-18  494  	}
344ff358495706a Angela Czubak       2025-08-18  495  	haptic->stop_effect.input_dev = dev;
344ff358495706a Angela Czubak       2025-08-18  496  	INIT_WORK(&haptic->stop_effect.work, haptic_work_handler);
344ff358495706a Angela Czubak       2025-08-18  497  	fill_effect_buf(haptic, &stop_effect, &haptic->stop_effect,
344ff358495706a Angela Czubak       2025-08-18  498  			HID_HAPTIC_ORDINAL_WAVEFORMSTOP);
344ff358495706a Angela Czubak       2025-08-18  499  
344ff358495706a Angela Czubak       2025-08-18  500  	input_set_capability(dev, EV_FF, FF_HAPTIC);
344ff358495706a Angela Czubak       2025-08-18  501  
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  502  	if (!try_module_get(THIS_MODULE)) {
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  503  		dev_err(&hdev->dev, "Failed to increase module count.\n");
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  504  		ret = -ENODEV;
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  505  		goto ff_cap_clear;
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  506  	}
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  507  	if (!get_device(&hdev->dev)) {
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  508  		dev_err(&hdev->dev, "Failed to get hdev device.\n");
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  509  		ret = -ENODEV;
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  510  		module_put(THIS_MODULE);
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  511  		goto ff_cap_clear;
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  512  	}
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  513  
344ff358495706a Angela Czubak       2025-08-18  514  	ret = input_ff_create(dev, FF_MAX_EFFECTS);
344ff358495706a Angela Czubak       2025-08-18  515  	if (ret) {
344ff358495706a Angela Czubak       2025-08-18  516  		dev_err(&hdev->dev, "Failed to create ff device.\n");
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  517  		put_device(&hdev->dev);
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  518  		module_put(THIS_MODULE);
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  519  		goto ff_cap_clear;
344ff358495706a Angela Czubak       2025-08-18  520  	}
344ff358495706a Angela Czubak       2025-08-18  521  
344ff358495706a Angela Czubak       2025-08-18  522  	ff = dev->ff;
344ff358495706a Angela Czubak       2025-08-18  523  	ff->private = haptic;
344ff358495706a Angela Czubak       2025-08-18  524  	ff->upload = hid_haptic_upload_effect;
344ff358495706a Angela Czubak       2025-08-18  525  	ff->playback = hid_haptic_playback;
344ff358495706a Angela Czubak       2025-08-18  526  	ff->erase = hid_haptic_erase;
344ff358495706a Angela Czubak       2025-08-18  527  	ff->destroy = hid_haptic_destroy;
344ff358495706a Angela Czubak       2025-08-18  528  	return 0;
344ff358495706a Angela Czubak       2025-08-18  529  
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  530  ff_cap_clear:
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  531  	__clear_bit(FF_HAPTIC, dev->ffbit);
7668dc668064c7a Aldo Ariel Panzardo 2026-10-16  532  	__clear_bit(EV_FF, dev->evbit);
344ff358495706a Angela Czubak       2025-08-18 @533  stop_buffer_free:
344ff358495706a Angela Czubak       2025-08-18  534  	kfree(haptic->stop_effect.report_buf);
344ff358495706a Angela Czubak       2025-08-18  535  	haptic->stop_effect.report_buf = NULL;
344ff358495706a Angela Czubak       2025-08-18  536  buffer_free:
344ff358495706a Angela Czubak       2025-08-18  537  	while (--r >= 0)
344ff358495706a Angela Czubak       2025-08-18  538  		kfree(haptic->effect[r].report_buf);
344ff358495706a Angela Czubak       2025-08-18  539  	kfree(haptic->effect);
344ff358495706a Angela Czubak       2025-08-18  540  	haptic->effect = NULL;
344ff358495706a Angela Czubak       2025-08-18  541  output_queue:
344ff358495706a Angela Czubak       2025-08-18  542  	destroy_workqueue(haptic->wq);
344ff358495706a Angela Czubak       2025-08-18  543  	haptic->wq = NULL;
344ff358495706a Angela Czubak       2025-08-18  544  duration_map:
344ff358495706a Angela Czubak       2025-08-18  545  	kfree(haptic->duration_map);
344ff358495706a Angela Czubak       2025-08-18  546  	haptic->duration_map = NULL;
344ff358495706a Angela Czubak       2025-08-18  547  usage_map:
344ff358495706a Angela Czubak       2025-08-18  548  	kfree(haptic->hid_usage_map);
344ff358495706a Angela Czubak       2025-08-18  549  	haptic->hid_usage_map = NULL;
344ff358495706a Angela Czubak       2025-08-18  550  exit:
344ff358495706a Angela Czubak       2025-08-18  551  	return ret;
344ff358495706a Angela Czubak       2025-08-18  552  }
344ff358495706a Angela Czubak       2025-08-18  553  EXPORT_SYMBOL_GPL(hid_haptic_init);
a77efca3aa85e38 Angela Czubak       2025-08-18  554  

--
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2026-10-17 11:49 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <20261009103333.2476105-1-qwe.aldo@gmail.com>
2026-10-16 13:55 ` [PATCH v5 0/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
2026-10-16 13:55   ` [PATCH v5 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
2026-10-16 13:55   ` [PATCH v5 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
2026-10-16 15:13   ` [PATCH v6 0/2] " Aldo Ariel Panzardo
2026-10-16 15:13     ` [PATCH v6 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
2026-10-16 15:13     ` [PATCH v6 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
2026-10-16 16:33     ` [PATCH v7 0/2] " Aldo Ariel Panzardo
2026-10-16 16:33       ` [PATCH v7 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
2026-10-16 18:16         ` Dmitry Torokhov
2026-10-16 16:33       ` [PATCH v7 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
2026-10-16 17:30       ` [PATCH v8 0/2] " Aldo Ariel Panzardo
2026-10-16 17:30         ` [PATCH v8 1/2] HID: haptic: reorder try_module_get/get_device before input_ff_create Aldo Ariel Panzardo
2026-10-17 11:49           ` kernel test robot
2026-10-16 17:30         ` [PATCH v8 2/2] HID: multitouch: fix use-after-free of haptic data on delayed input release Aldo Ariel Panzardo
2026-10-16 18:27           ` Dmitry Torokhov

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®