Linux Input/HID development
 help / color / mirror / Atom feed
From: sashiko-bot@kernel.org
To: "Haoxiang Li" <haoxiang_li2024@163.com>
Cc: dmitry.torokhov@gmail.com, linux-input@vger.kernel.org
Subject: Re: [PATCH] HID: logitech-hidpp: Fix FF device cleanup on init failure
Date: Tue, 23 Jun 2026 07:07:08 +0000	[thread overview]
Message-ID: <20260623070708.79F691F000E9@smtp.kernel.org> (raw)
In-Reply-To: <20260623065200.1966629-1-haoxiang_li2024@163.com>

Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:

New issues:
- [High] Calling `input_ff_destroy(dev)` leaves a dangling `dev->flush` pointer, causing a guaranteed NULL pointer dereference when the device file is closed.
- [High] Calling `input_ff_destroy(dev)` on an active, registered device in the error path introduces a Use-After-Free race condition.

Pre-existing issues:
- [Critical] Use-After-Free in `hidpp_ff_destroy()` due to mismatched lifecycles between `devm`-managed driver data and `input_dev` lifecycle.
- [High] Input device capabilities are initialized after registration, violating subsystem lifecycle rules and exposing incomplete state to userspace.
--

commit 1a99b024f97c7dab9fe8188d726db401b73dd317
Author: Haoxiang Li <haoxiang_li2024@163.com>

    HID: logitech-hidpp: Fix FF device cleanup on init failure

    hidpp_ff_init() creates the input force-feedback device with
    input_ff_create(), then allocates the HID++ FF private data,
    effect ID array, and workqueue.
    
    If any of those allocations fail after input_ff_create() succeeds,
    the function returns an error without destroying the FF device.
    Add an unwind path that frees the private allocations made by
    hidpp_ff_init() and calls input_ff_destroy() for failures after
    input_ff_create() succeeds.

diff --git a/drivers/hid/hid-logitech-hidpp.c b/drivers/hid/hid-logitech-hidpp.c
index ccbf28869a968..95f84efa77069 100644
--- a/drivers/hid/hid-logitech-hidpp.c
+++ b/drivers/hid/hid-logitech-hidpp.c
@@ -2859,18 +2859,19 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
 	 * ownership to FF core
 	 */

[Severity: High]
This is a pre-existing issue, but does initializing input device capabilities
after registration violate subsystem lifecycle rules and expose incomplete
state to userspace?

Because hidpp_probe() calls hid_connect() (which registers the device)
before calling hidpp_ff_init(), can userspace open the device and issue
ioctls immediately upon registration, before hidpp_ff_init() has fully
configured the FF capabilities:

    for (j = 0; hidpp_ff_effects[j] >= 0; j++)
        set_bit(hidpp_ff_effects[j], dev->ffbit);

>  	data = kmemdup(data, sizeof(*data), GFP_KERNEL);
> -	if (!data)
> -		return -ENOMEM;
> +	if (!data) {
> +		error = -ENOMEM;
> +		goto err_destroy_ff;
> +	}

[ ... ]

>  	data->wq = create_singlethread_workqueue("hidpp-ff-sendqueue");
>  	if (!data->wq) {
> -		kfree(data->effect_ids);
> -		kfree(data);
> -		return -ENOMEM;
> +		error = -ENOMEM;
> +		goto err_free_effect_ids;
>  	}
>  
>  	data->hidpp = hidpp;

[Severity: Critical]
This is a pre-existing issue, but could this lead to a use-after-free in
hidpp_ff_destroy() due to mismatched lifecycles?

The hidpp_device structure is allocated using devm_kzalloc() in hidpp_probe(),
meaning it is freed by devres immediately after the driver's remove()
callback completes.

However, the input_dev is reference-counted and outlives the driver binding
if a userspace process holds the event file descriptor open. When the process
finally closes the fd, input_free_device() calls hidpp_ff_destroy(), which
dereferences data->hidpp to access hid_dev:

    struct hid_device *hid = data->hidpp->hid_dev;

Could this trigger a use-after-free if a local user holds the input device
open during a device unplug or driver unbind?

[ ... ]

> @@ -2900,6 +2901,14 @@ static int hidpp_ff_init(struct hidpp_device *hidpp,
>  		 version);
>  
>  	return 0;
> +
> +err_free_effect_ids:
> +	kfree(data->effect_ids);
> +err_free_data:
> +	kfree(data);
> +err_destroy_ff:
> +	input_ff_destroy(dev);

[Severity: High]
Is it possible that calling input_ff_destroy(dev) here leaves a dangling
dev->flush pointer?

This frees dev->ff but does not clear the dev->flush = input_ff_flush
callback set earlier by input_ff_create().

Since hidpp_probe() ignores the initialization error, the input device
remains registered. If a userspace process opens and then closes the event
node, evdev_release() calls input_flush_device(), triggering
input_ff_flush():

    guard(mutex)(&ff->mutex);

Does this cause a guaranteed NULL pointer dereference because dev->ff is now
NULL?

[Severity: High]
Additionally, since hidpp_ff_init() runs after hid_connect() has already
registered the device, it is visible to userspace.

If input_ff_create() succeeds, it sets the EV_FF bit. If a concurrent thread
immediately issues an EVIOCSFF ioctl, calling input_ff_upload() which uses
dev->ff, and this error path triggers simultaneously calling
input_ff_destroy(dev):

    input_ff_destroy(dev);

Could this regression result in a use-after-free in the force-feedback ioctl
handler without any synchronization?

-- 
Sashiko AI review · https://sashiko.dev/#/patchset/20260623065200.1966629-1-haoxiang_li2024@163.com?part=1

      reply	other threads:[~2026-06-23  7:07 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-06-23  6:52 [PATCH] HID: logitech-hidpp: Fix FF device cleanup on init failure Haoxiang Li
2026-06-23  7:07 ` sashiko-bot [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20260623070708.79F691F000E9@smtp.kernel.org \
    --to=sashiko-bot@kernel.org \
    --cc=dmitry.torokhov@gmail.com \
    --cc=haoxiang_li2024@163.com \
    --cc=linux-input@vger.kernel.org \
    --cc=sashiko-reviews@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox