diff options
| author | Jose VillaseƱor Montfort <pepemontfort@gmail.com> | 2026-08-26 09:47:02 -0400 |
|---|---|---|
| committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2026-09-02 14:26:43 +0200 |
| commit | c3597923932bb90d4fc2186aef552f6677175e4a (patch) | |
| tree | d48fdbaf1720006ef5d66c0d56b2cbd7f8f13bd1 | |
| parent | 1007a6b429d756513abd25bd00290908f2e89a4a (diff) | |
| download | linux-stable-c3597923932bb90d4fc2186aef552f6677175e4a.tar.gz linux-stable-c3597923932bb90d4fc2186aef552f6677175e4a.zip | |
HID: magicmouse: do not keep a stale msc->input if no input is claimed
[ Upstream commit 0af3b89705688af01aa06025b84fa7a1e06ba6cc ]
magicmouse_input_mapping() caches the first hid_input's input_dev in
msc->input while the report descriptor is parsed, and the rest of the
driver treats a non-NULL msc->input as proof that an input device was
registered.
That does not hold on the hid-input error path. If hidinput_connect()
fails -- for instance because input_register_device() returns an error --
it unwinds through hidinput_disconnect(), which frees every input_dev it
created, including the one cached in msc->input.
The failure does not abort the probe. hid_connect() only skips the claim:
if ((connect_mask & HID_CONNECT_HIDINPUT) && !hidinput_connect(hdev,
connect_mask & HID_CONNECT_HIDINPUT_FORCE))
hdev->claimed |= HID_CLAIMED_INPUT;
and the "device has no listeners" bailout below it does not fire for this
driver, which sets ->raw_event; on the USB Magic Mouse 2 / Magic Trackpad
2 paths hidraw and hiddev are claimed as well. hid_hw_start() therefore
returns 0 and magicmouse_probe() continues with msc->input pointing at
freed memory. Being non-NULL, it passes the "input not registered" check
in probe and the NULL checks in ->raw_event and ->event, so the next
input report dereferences freed memory.
Clear msc->input when the HID core did not claim an input device, so the
existing NULL checks cover this case as well.
Fixes: f1a9a149abc8 ("HID: magicmouse: fix race between input_register() and probe()")
Link: https://lore.kernel.org/linux-input/20260728185542.65F091F000E9@smtp.kernel.org/
Cc: stable@vger.kernel.org
Signed-off-by: Jose VillaseƱor Montfort <pepemontfort@gmail.com>
Reviewed-by: Alec Hall <signshop.alec@gmail.com>
Tested-by: Alec Hall <signshop.alec@gmail.com>
Signed-off-by: Jiri Kosina <jkosina@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
| -rw-r--r-- | drivers/hid/hid-magicmouse.c | 10 |
1 files changed, 10 insertions, 0 deletions
diff --git a/drivers/hid/hid-magicmouse.c b/drivers/hid/hid-magicmouse.c index 13bb9e040d33..b3f8d8b878a5 100644 --- a/drivers/hid/hid-magicmouse.c +++ b/drivers/hid/hid-magicmouse.c @@ -643,6 +643,16 @@ static int magicmouse_probe(struct hid_device *hdev, return ret; } + /* + * When hidinput_connect() fails it frees every input device it + * created, but that does not fail hid_hw_start(): the core simply + * does not claim an input. msc->input, cached in ->input_mapping + * while the report descriptor was parsed, would then be a dangling + * pointer that passes every NULL check. Trust the core's claim. + */ + if (!(hdev->claimed & HID_CLAIMED_INPUT)) + msc->input = NULL; + if (!msc->input) { hid_err(hdev, "magicmouse input not registered\n"); ret = -ENOMEM; |
