From: Qasim Ijaz <qasdev00@gmail.com>
To: jikos@kernel.org, bentiss@kernel.org
Cc: gargaditya08@live.com, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org, stable@vger.kernel.org
Subject: [PATCH] HID: appletb-kbd: fix memory corruption of input_handler_list
Date: Thu, 26 Jun 2025 23:47:11 +0100 [thread overview]
Message-ID: <20250626224711.13980-1-qasdev00@gmail.com> (raw)
In appletb_kbd_probe an input handler is initialised and then registered
with input core through input_register_handler(). When this happens input
core will add the input handler (specifically its node) to the global
input_handler_list. The input_handler_list is central to the functionality
of input core and is traversed in various places in input core. An example
of this is when a new input device is plugged in and gets registered with
input core.
The input_handler in probe is allocated as device managed memory. If a
probe failure occurs after input_register_handler() the input_handler
memory is freed, yet it will remain in the input_handler_list. This
effectively means the input_handler_list contains a dangling pointer
to data belonging to a freed input handler.
This causes an issue when any other input device is plugged in - in my
case I had an old PixArt HP USB optical mouse and I decided to
plug it in after a failure occurred after input_register_handler().
This lead to the registration of this input device via
input_register_device which involves traversing over every handler
in the corrupted input_handler_list and calling input_attach_handler(),
giving each handler a chance to bind to newly registered device.
The core of this bug is a UAF which causes memory corruption of
input_handler_list and to fix it we must ensure the input handler is
unregistered from input core, this is done through
input_unregister_handler().
[ 63.191597] ==================================================================
[ 63.192094] BUG: KASAN: slab-use-after-free in input_attach_handler.isra.0+0x1a9/0x1e0
[ 63.192094] Read of size 8 at addr ffff888105ea7c80 by task kworker/0:2/54
[ 63.192094]
[ 63.192094] CPU: 0 UID: 0 PID: 54 Comm: kworker/0:2 Not tainted 6.16.0-rc2-00321-g2aa6621d
[ 63.192094] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.2-debian-1.164
[ 63.192094] Workqueue: usb_hub_wq hub_event
[ 63.192094] Call Trace:
[ 63.192094] <TASK>
[ 63.192094] dump_stack_lvl+0x53/0x70
[ 63.192094] print_report+0xce/0x670
[ 63.192094] ? input_attach_handler.isra.0+0x1a9/0x1e0
[ 63.192094] kasan_report+0xce/0x100
[ 63.192094] ? input_attach_handler.isra.0+0x1a9/0x1e0
[ 63.192094] input_attach_handler.isra.0+0x1a9/0x1e0
[ 63.192094] input_register_device+0x76c/0xd00
[ 63.192094] hidinput_connect+0x686d/0xad60
[ 63.192094] ? __pfx_hidinput_connect+0x10/0x10
[ 63.192094] ? xhci_urb_enqueue+0x523/0x930
[ 63.192094] hid_connect+0xf20/0x1b10
[ 63.192094] ? mutex_unlock+0x7d/0xd0
[ 63.192094] ? __pfx_mutex_unlock+0x10/0x10
[ 63.192094] ? __pm_runtime_idle+0x95/0x1c0
[ 63.192094] ? __pfx_hid_connect+0x10/0x10
[ 63.192094] hid_hw_start+0x83/0x100
[ 63.192094] hid_device_probe+0x2d1/0x680
[ 63.192094] really_probe+0x1c3/0x690
[ 63.192094] __driver_probe_device+0x247/0x300
[ 63.192094] driver_probe_device+0x49/0x210
[ 63.192094] __device_attach_driver+0x160/0x320
[ 63.192094] ? __pfx___device_attach_driver+0x10/0x10
[ 63.192094] bus_for_each_drv+0x10f/0x190
[ 63.192094] ? __pfx_bus_for_each_drv+0x10/0x10
[ 63.192094] __device_attach+0x18e/0x370
[ 63.192094] ? __pfx___device_attach+0x10/0x10
[ 63.192094] ? kobject_get+0x50/0xe0
[ 63.192094] bus_probe_device+0x123/0x170
[ 63.192094] device_add+0xd4d/0x1460
[ 63.192094] ? __pfx_device_add+0x10/0x10
[ 63.192094] ? up_write+0x4d/0x90
[ 63.192094] ? __debugfs_create_file+0x377/0x5a0
[ 63.192094] hid_add_device+0x30b/0x910
[ 63.192094] ? __pfx_hid_add_device+0x10/0x10
[ 63.192094] usbhid_probe+0x920/0xe00
[ 63.192094] ? pm_runtime_enable+0xfa/0x2a0
[ 63.192094] usb_probe_interface+0x363/0x9a0
[ 63.192094] ? sysfs_do_create_link_sd+0x89/0x100
[ 63.192094] really_probe+0x1c3/0x690
[ 63.192094] __driver_probe_device+0x247/0x300
[ 63.192094] driver_probe_device+0x49/0x210
[ 63.192094] __device_attach_driver+0x160/0x320
[ 63.192094] ? __pfx___device_attach_driver+0x10/0x10
[ 63.192094] bus_for_each_drv+0x10f/0x190
[ 63.192094] ? __pfx_bus_for_each_drv+0x10/0x10
[ 63.192094] __device_attach+0x18e/0x370
[ 63.192094] ? __pfx___device_attach+0x10/0x10
[ 63.192094] ? kobject_get+0x50/0xe0
[ 63.192094] bus_probe_device+0x123/0x170
[ 63.192094] device_add+0xd4d/0x1460
[ 63.192094] ? __pfx_device_add+0x10/0x10
[ 63.192094] ? mutex_unlock+0x7d/0xd0
[ 63.192094] ? __pfx_mutex_unlock+0x10/0x10
[ 63.192094] usb_set_configuration+0xd14/0x1880
[ 63.192094] usb_generic_driver_probe+0x78/0xb0
[ 63.192094] usb_probe_device+0xaa/0x2e0
[ 63.192094] really_probe+0x1c3/0x690
[ 63.192094] __driver_probe_device+0x247/0x300
[ 63.192094] ? usb_generic_driver_match+0x58/0x80
[ 63.192094] driver_probe_device+0x49/0x210
[ 63.192094] __device_attach_driver+0x160/0x320
[ 63.192094] ? __pfx___device_attach_driver+0x10/0x10
[ 63.192094] bus_for_each_drv+0x10f/0x190
[ 63.192094] ? __pfx_bus_for_each_drv+0x10/0x10
[ 63.192094] __device_attach+0x18e/0x370
[ 63.192094] ? __pfx___device_attach+0x10/0x10
[ 63.192094] ? kobject_get+0x50/0xe0
[ 63.192094] bus_probe_device+0x123/0x170
[ 63.192094] device_add+0xd4d/0x1460
[ 63.192094] ? __pfx_device_add+0x10/0x10
[ 63.192094] ? add_device_randomness+0xb2/0xe0
[ 63.192094] usb_new_device+0x7b4/0x1000
[ 63.192094] hub_event+0x234d/0x3fa0
[ 63.192094] ? __pfx_hub_event+0x10/0x10
[ 63.192094] ? _raw_spin_lock_irqsave+0x85/0xe0
[ 63.192094] ? _raw_spin_lock_irqsave+0x85/0xe0
[ 63.192094] ? mutex_unlock+0x7d/0xd0
[ 63.192094] ? _raw_spin_lock_irq+0x80/0xe0
[ 63.192094] ? __pfx__raw_spin_lock_irq+0x10/0x10
[ 63.192094] ? __pm_runtime_suspend+0x74/0x1c0
[ 63.192094] process_one_work+0x5bf/0xfe0
[ 63.192094] worker_thread+0x777/0x13a0
[ 63.192094] ? __kthread_parkme+0x99/0x180
[ 63.192094] ? __pfx_worker_thread+0x10/0x10
[ 63.192094] kthread+0x327/0x630
[ 63.192094] ? __pfx_kthread+0x10/0x10
[ 63.192094] ? __pfx__raw_spin_lock_irq+0x10/0x10
[ 63.192094] ? __pfx_kthread+0x10/0x10
[ 63.192094] ? __pfx_kthread+0x10/0x10
[ 63.192094] ret_from_fork+0xff/0x1a0
[ 63.192094] ? __pfx_kthread+0x10/0x10
[ 63.192094] ret_from_fork_asm+0x1a/0x30
[ 63.192094] </TASK>
[ 63.192094]
[ 63.192094] Allocated by task 54:
[ 63.192094] kasan_save_stack+0x33/0x60
[ 63.192094] kasan_save_track+0x14/0x30
[ 63.192094] __kasan_kmalloc+0x8f/0xa0
[ 63.192094] __kmalloc_node_track_caller_noprof+0x195/0x420
[ 63.192094] devm_kmalloc+0x74/0x1e0
[ 63.192094] appletb_kbd_probe+0x39/0x440
[ 63.192094] hid_device_probe+0x2d1/0x680
[ 63.192094] really_probe+0x1c3/0x690
[ 63.192094] __driver_probe_device+0x247/0x300
[ 63.192094] driver_probe_device+0x49/0x210
[ 63.192094] __device_attach_driver+0x160/0x320
[...]
[ 63.192094]
[ 63.192094] Freed by task 54:
[ 63.192094] kasan_save_stack+0x33/0x60
[ 63.192094] kasan_save_track+0x14/0x30
[ 63.192094] kasan_save_free_info+0x3b/0x60
[ 63.192094] __kasan_slab_free+0x37/0x50
[ 63.192094] kfree+0xcf/0x360
[ 63.192094] devres_release_group+0x1f8/0x3c0
[ 63.192094] hid_device_probe+0x315/0x680
[ 63.192094] really_probe+0x1c3/0x690
[ 63.192094] __driver_probe_device+0x247/0x300
[ 63.192094] driver_probe_device+0x49/0x210
[ 63.192094] __device_attach_driver+0x160/0x320
[...]
Fixes: 93a0fc489481 ("HID: hid-appletb-kbd: add support for automatic brightness control while using the touchbar")
Cc: stable@vger.kernel.org
Signed-off-by: Qasim Ijaz <qasdev00@gmail.com>
---
drivers/hid/hid-appletb-kbd.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hid/hid-appletb-kbd.c b/drivers/hid/hid-appletb-kbd.c
index d11c49665147..271d1b27b8dd 100644
--- a/drivers/hid/hid-appletb-kbd.c
+++ b/drivers/hid/hid-appletb-kbd.c
@@ -430,13 +430,15 @@ static int appletb_kbd_probe(struct hid_device *hdev, const struct hid_device_id
ret = appletb_kbd_set_mode(kbd, appletb_tb_def_mode);
if (ret) {
dev_err_probe(dev, ret, "Failed to set touchbar mode\n");
- goto close_hw;
+ goto unregister_handler;
}
hid_set_drvdata(hdev, kbd);
return 0;
+unregister_handler:
+ input_unregister_handler(&kbd->inp_handler);
close_hw:
if (kbd->backlight_dev) {
put_device(&kbd->backlight_dev->dev);
--
2.39.5
next reply other threads:[~2025-06-26 22:47 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-06-26 22:47 Qasim Ijaz [this message]
2025-06-27 5:27 ` [PATCH] HID: appletb-kbd: fix memory corruption of input_handler_list Aditya Garg
2025-06-27 10:49 ` Qasim Ijaz
2025-06-27 5:33 ` Jiri Slaby
2025-06-27 10:50 ` Qasim Ijaz
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=20250626224711.13980-1-qasdev00@gmail.com \
--to=qasdev00@gmail.com \
--cc=bentiss@kernel.org \
--cc=gargaditya08@live.com \
--cc=jikos@kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=stable@vger.kernel.org \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.