From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
To: "Habil Eren Türker" <habilerenturker@gmail.com>
Cc: "Habil Eren Türker" <habilerenturker@hotmail.com>,
sashiko-bot@kernel.org, linux-input@vger.kernel.org,
linux-kernel@vger.kernel.org, sashiko-reviews@lists.linux.dev
Subject: Re: [PATCH v2] Input: fix potential use-after-free in input_devices_seq_show
Date: Wed, 30 Sep 2026 11:15:22 -0700 [thread overview]
Message-ID: <ar1RZeMi9OK4Gro2@google.com> (raw)
In-Reply-To: <20260928181704.61015-1-habilerenturker@hotmail.com>
Hi Türker,
On Mon, Sep 28, 2026 at 09:15:24PM +0300, Habil Eren Türker wrote:
> This patch is withdrawn.
>
> Sashiko's assessment is correct. input_mutex already protects the device
> during seq_file iteration, so the explicit refcounting is unnecessary.
> Additionally, the patch had two bugs: a refcount imbalance in next() and
> a missing IS_ERR() check in stop(), which could lead to a kernel panic
> or use-after-free.
>
> I will investigate the actual root cause further.
To save you some time digging through the syzbot reports I had an LLM
scan them and here are the findings:
It is not the struct input_dev itself that is being freed while on
input_dev_list, but rather the strings pointed to by dev->name or
dev->phys when a driver either fails to unregister its input device
before freeing its private data, or leaks an input_dev instance.
Because syzbot groups KASAN crashes by the top frame (string_nocheck() ->
string() -> vsnprintf() -> seq_printf()), the 63 crash reports under
https://syzkaller.appspot.com/bug?extid=bc6b37960b1d13f68f9f actually
belong to three separate bugs:
1. 25 of the 63 reports crash in irq_seq_show() (kernel/irq/proc.c:601)
when reading /proc/interrupts, which is unrelated to input.
2. 29 of the reports (including the initial syzbot report [1]) crash in
input_devices_seq_show() on line 1178 when formatting dev->name:
seq_printf(seq, "N: Name=\"%s\"\n", dev->name ? dev->name : "");
In all 29 reports, the bad read is at offset 0x758 (1880 bytes) inside
a kmalloc-2k object. In most runs that slab slot had already exited
the KASAN quarantine and been reallocated (for example by netlink
__alloc_skb() or sk_prot_alloc()), masking the original owner.
However, one report [2] (log [3]) caught the object before reuse:
Allocated by: redrat3_dev_probe() (drivers/media/rc/redrat3.c:1023)
Freed by: redrat3_delete() <- redrat3_dev_probe() (redrat3.c:1124)
redrat3_init_rc_dev() registered the rc_dev (and its input_dev, with
input_dev->name pointing to rr3->name at offset 0x758 of struct
redrat3_dev), and when redrat3_enable_detector() subsequently failed,
the error path freed rr3 without calling rc_unregister_device(),
leaving the input_dev registered with a dangling dev->name pointer.
This is already fixed in linux-next by commit af452b9e0133 ("media:
redrat3: fix UAF in probe error path leaving rc device registered").
3. The remaining 9 reports crash in input_devices_seq_show() on the next
line (drivers/input/input.c:1179) when formatting dev->phys:
seq_printf(seq, "P: Phys=%s\n", dev->phys ? dev->phys : "");
(dev->name does not fault there because xpad->name points to a static
string literal in xpad_device[].) All 9 reports read offset 0x220
(544 bytes) inside a kmalloc-1k object (offsetof(struct usb_xpad,
phys)). Two reports [4] (log [5]) and [6] caught the struct usb_xpad
object before slab reuse:
Allocated by: xpad_probe() (drivers/input/joystick/xpad.c:2052)
Freed by: xpad_disconnect() (drivers/input/joystick/xpad.c:2236)
Last work: xpad360w_process_packet() <- xpad_irq_in()
In xpad360w_process_packet(), xpad->pad_present is updated in URB
completion context and schedules xpad->work (xpad_presence_work()).
If presence packets toggle xpad->pad_present (true -> false -> true)
before xpad_presence_work() runs, xpad_presence_work() sees
xpad->pad_present == true and calls xpad_init_input() again even
though xpad->input_created is already true. That overwrites xpad->dev
(and xpad->led) and leaks the old input_dev on input_dev_list (in [5]
it registers input69 through input79 on the same USB interface). When
xpad_disconnect() later runs, xpad_deinit_input() only unregisters
the last xpad->dev and frees xpad, leaving the leaked input_dev
instances on input_dev_list with dev->phys pointing into freed
xpad->phys.
[1] https://syzkaller.appspot.com/text?tag=CrashReport&x=12bef8c9580000
[2] https://syzkaller.appspot.com/text?tag=CrashReport&x=15d46e79580000
[3] https://syzkaller.appspot.com/text?tag=CrashLog&x=16cc5679580000
[4] https://syzkaller.appspot.com/text?tag=CrashReport&x=115fd67e580000
[5] https://syzkaller.appspot.com/text?tag=CrashLog&x=17f40456580000
[6] https://syzkaller.appspot.com/text?tag=CrashReport&x=11131092580000
Thanks.
--
Dmitry
next prev parent reply other threads:[~2026-09-30 18:15 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-28 17:11 [PATCH v2] Input: fix potential use-after-free in input_devices_seq_show Habil Eren Türker
2026-09-28 17:21 ` sashiko-bot
2026-09-28 18:15 ` Habil Eren Türker
2026-09-30 18:15 ` Dmitry Torokhov [this message]
2026-10-01 16:04 ` Habil Eren Türker
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=ar1RZeMi9OK4Gro2@google.com \
--to=dmitry.torokhov@gmail.com \
--cc=habilerenturker@gmail.com \
--cc=habilerenturker@hotmail.com \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=sashiko-bot@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 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.