From: Cen Zhang <zzzccc427@gmail.com>
To: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Cc: linux-usb@vger.kernel.org, linux-kernel@vger.kernel.org,
baijiaju1990@gmail.com, zzzccc427@gmail.com
Subject: [PATCH] USB: iowarrior: kill async writes before freeing on disconnect
Date: Thu, 18 Jun 2026 18:41:26 +0800 [thread overview]
Message-ID: <20260618104126.3392136-1-zzzccc427@gmail.com> (raw)
IOWarrior write() uses anchored interrupt URBs for async-capable
devices and passes struct iowarrior as the completion context.
release() can close the file while those URBs are still outstanding; it
only stops the interrupt-in URB when the device is still present.
disconnect() already kills the submitted write URBs when the device is
still opened, but skips that step when opened is clear and then frees
struct iowarrior. That allows a close-before-disconnect sequence to free
the embedded anchor and completion context while giveback is still using
them.
The buggy scenario involves two paths, with each column showing the order
within that path:
file write and close path: disconnect and giveback path:
1. write() submits an anchored 1. USB disconnect sets present to 0.
interrupt-out URB.
2. release() sets opened to 0 2. Because opened is 0, disconnect
and returns without draining skips the write-anchor drain and
dev->submitted. frees dev.
3. The write URB remains in 3. Giveback unanchors the URB and
flight after close. runs iowarrior_write_callback()
with the freed dev.
Kill the submitted write URBs in the opened == 0 disconnect branch before
dropping the device mutex and freeing the device. usb_kill_anchored_urbs()
waits for any completion window covered by the anchor, so the embedded
anchor and callback context remain live until write giveback is done.
Validation reproduced this kernel report:
KASAN slab-use-after-free in iowarrior_write_callback+0x7d/0xf0
RIP: 0010:pv_native_safe_halt+0xf/0x20
Write of size 4
Call trace:
dump_stack_lvl+0x66/0xa0
print_report+0xce/0x630
fixup_red_left+0x9/0x30
complete_report_info+0x83/0x110
iowarrior_write_callback+0x7d/0xf0 (drivers/usb/misc/iowarrior.c:220)
kasan_report+0xe0/0x110
kasan_check_range+0x105/0x1b0
__usb_hcd_giveback_urb+0x112/0x1d0
dummy_timer+0xaaa/0x19a0
dummy_timer+0x4/0x19a0
srso_alias_return_thunk+0x5/0xfbef5
__hrtimer_run_queues+0xeb/0x510
__hrtimer_run_queues+0x102/0x510
hrtimer_run_softirq+0xd0/0x130
handle_softirqs+0x155/0x650
do_raw_spin_unlock+0x9a/0x100
do_raw_spin_unlock+0x8b/0x100
__irq_exit_rcu+0xc4/0x160
irq_exit_rcu+0xe/0x20
sysvec_apic_timer_interrupt+0x6c/0x80
asm_sysvec_apic_timer_interrupt+0x1a/0x20
Allocated by task stack:
kasan_save_stack+0x33/0x60
kasan_save_track+0x14/0x30
__kasan_kmalloc+0x8f/0xa0
__device_attach_driver+0xf1/0x1a0
bus_for_each_drv+0xf9/0x160
__device_attach+0x133/0x2a0
device_add+0x9b9/0xc10
usb_set_configuration+0xb64/0xf20
usb_new_device+0x492/0x870
hub_event+0x1b10/0x29c0
process_one_work+0x4d7/0xb90
worker_thread+0x2d8/0x570
kthread+0x1ad/0x1f0
ret_from_fork+0x3c9/0x540
ret_from_fork_asm+0x1a/0x30
Fixes: 946b960d13c1 ("USB: add driver for iowarrior devices.")
Assisted-by: Codex:gpt-5.5
Signed-off-by: Cen Zhang <zzzccc427@gmail.com>
---
drivers/usb/misc/iowarrior.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/usb/misc/iowarrior.c b/drivers/usb/misc/iowarrior.c
index 22504c0a2841..07406ec7aabe 100644
--- a/drivers/usb/misc/iowarrior.c
+++ b/drivers/usb/misc/iowarrior.c
@@ -917,6 +917,7 @@ static void iowarrior_disconnect(struct usb_interface *interface)
mutex_unlock(&dev->mutex);
} else {
/* no process is using the device, cleanup now */
+ usb_kill_anchored_urbs(&dev->submitted);
mutex_unlock(&dev->mutex);
iowarrior_delete(dev);
}
--
2.43.0
next reply other threads:[~2026-06-18 10:41 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-18 10:41 Cen Zhang [this message]
2026-06-18 13:20 ` [PATCH] USB: iowarrior: kill async writes before freeing on disconnect Johan Hovold
2026-06-18 13:29 ` Cen Zhang
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=20260618104126.3392136-1-zzzccc427@gmail.com \
--to=zzzccc427@gmail.com \
--cc=baijiaju1990@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-usb@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox