* [BUG] KASAN: slab-use-after-free Read in usx2y_async_seq04_init
@ 2026-09-11 15:53 Farhad Alemi
2026-09-12 12:34 ` Takashi Iwai
0 siblings, 1 reply; 2+ messages in thread
From: Farhad Alemi @ 2026-09-11 15:53 UTC (permalink / raw)
To: Jaroslav Kysela, Takashi Iwai; +Cc: linux-sound, linux-kernel
[-- Attachment #1: Type: text/plain, Size: 10646 bytes --]
Hello,
We are reporting the following crash (reproducer attached):
Linux version 7.3.0-rc2 50d05c7c76c96b90462f24debacca971d2e86713
Build Config: UpstreamAppArmorKASAN (KASAN + UBSAN, panic_on_warn=1)
[ 44.599577][ T9507] BUG: KASAN: slab-use-after-free in
usx2y_async_seq04_init+0x2b8/0x360
[ 44.599666][ T9507] Read of size 4 at addr ffff8881060f6000 by task
repro/9507
[ 44.599694][ T9507]
[ 44.599736][ T9507] CPU: 1 UID: 0 PID: 9507 Comm: repro Not tainted
7.3.0-rc2-00099-g50d05c7c76c9 #1 PREEMPT(full)
[ 44.599774][ T9507] Hardware name: QEMU Standard PC (Q35 + ICH9,
2009), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[ 44.599807][ T9507] Call Trace:
[ 44.599827][ T9507] <TASK>
[ 44.599877][ T9507] dump_stack_lvl+0xe8/0x150
[ 44.599917][ T9507] print_address_description+0x55/0x1e0
[ 44.599952][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.599982][ T9507] print_report+0x58/0x70
[ 44.600012][ T9507] kasan_report+0x117/0x150
[ 44.600055][ T9507] ? __kmalloc_noprof+0x1af/0x720
[ 44.600093][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.600130][ T9507] usx2y_async_seq04_init+0x2b8/0x360
[ 44.600168][ T9507] snd_usx2y_hwdep_dsp_load+0x232/0x5e0
[ 44.600205][ T9507] ? __pfx_snd_usx2y_hwdep_dsp_load+0x10/0x10
[ 44.600247][ T9507] snd_hwdep_ioctl+0x489/0x590
[ 44.600288][ T9507] ? __pfx_snd_usx2y_hwdep_dsp_load+0x10/0x10
[ 44.600322][ T9507] ? __pfx_snd_hwdep_ioctl+0x10/0x10
[ 44.600369][ T9507] ? __fget_files+0x2a/0x420
[ 44.600402][ T9507] ? __fget_files+0x2a/0x420
[ 44.600430][ T9507] ? __fget_files+0x3a0/0x420
[ 44.600460][ T9507] ? __fget_files+0x2a/0x420
[ 44.600491][ T9507] ? bpf_lsm_file_ioctl+0x9/0x20
[ 44.600525][ T9507] ? __pfx_snd_hwdep_ioctl+0x10/0x10
[ 44.600585][ T9507] __se_sys_ioctl+0xfc/0x170
[ 44.600625][ T9507] do_syscall_64+0x155/0x510
[ 44.600670][ T9507] ? trace_irq_disable+0x3b/0x140
[ 44.600709][ T9507] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 44.600741][ T9507] ? clear_bhb_loop+0x30/0x80
[ 44.600775][ T9507] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 44.600807][ T9507] RIP: 0033:0x41b46d
[ 44.600860][ T9507] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d
45 10 c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10
00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1a 48 8b 45 c8 64 48 2b 04 25
28 00 00 00
[ 44.600895][ T9507] RSP: 002b:00007f916b837100 EFLAGS: 00000246
ORIG_RAX: 0000000000000010
[ 44.600939][ T9507] RAX: ffffffffffffffda RBX: 00007f916b8376c0
RCX: 000000000041b46d
[ 44.600963][ T9507] RDX: 00007f916b837170 RSI: 0000000040604803
RDI: 0000000000000004
[ 44.600984][ T9507] RBP: 00007f916b837150 R08: 0000000000000000
R09: 00007f916b837174
[ 44.601006][ T9507] R10: 0000000000000008 R11: 0000000000000246
R12: 00007f916b8376c0
[ 44.601026][ T9507] R13: 00007fff5766a470 R14: 00007f916b837ce4
R15: 00007fff5766a567
[ 44.601060][ T9507] </TASK>
[ 44.601072][ T9507]
[ 44.601086][ T9507] Allocated by task 988:
[ 44.601102][ T9507] kasan_save_track+0x3e/0x80
[ 44.601139][ T9507] __kasan_kmalloc+0x93/0xb0
[ 44.601176][ T9507] __kmalloc_cache_noprof+0x325/0x610
[ 44.601211][ T9507] usb_alloc_dev+0x5d/0xf00
[ 44.601265][ T9507] hub_event+0x21ce/0x4f30
[ 44.601298][ T9507] process_scheduled_works+0xc99/0x1900
[ 44.601343][ T9507] worker_thread+0xa53/0xfc0
[ 44.601370][ T9507] kthread+0x38b/0x480
[ 44.601402][ T9507] ret_from_fork+0x514/0xb70
[ 44.601434][ T9507] ret_from_fork_asm+0x1a/0x30
[ 44.601467][ T9507]
[ 44.601475][ T9507] Freed by task 988:
[ 44.601489][ T9507] kasan_save_track+0x3e/0x80
[ 44.601523][ T9507] kasan_save_free_info+0x46/0x50
[ 44.601551][ T9507] __kasan_slab_free+0x5c/0x80
[ 44.601587][ T9507] kfree+0x1c5/0x650
[ 44.601614][ T9507] device_release+0xc4/0x1f0
[ 44.601649][ T9507] kobject_put+0x228/0x560
[ 44.601678][ T9507] hub_event+0x1cc9/0x4f30
[ 44.601711][ T9507] process_scheduled_works+0xc99/0x1900
[ 44.601754][ T9507] worker_thread+0xa53/0xfc0
[ 44.601780][ T9507] kthread+0x38b/0x480
[ 44.601812][ T9507] ret_from_fork+0x514/0xb70
[ 44.601844][ T9507] ret_from_fork_asm+0x1a/0x30
[ 44.601896][ T9507]
[ 44.601903][ T9507] The buggy address belongs to the object at
ffff8881060f6000
[ 44.601903][ T9507] which belongs to the cache kmalloc-2k of size 2048
[ 44.601939][ T9507] The buggy address is located 0 bytes inside of
[ 44.601939][ T9507] freed 2048-byte region [ffff8881060f6000,
ffff8881060f6800)
[ 44.601972][ T9507]
[ 44.601980][ T9507] The buggy address belongs to the physical page:
[ 44.602011][ T9507] page: refcount:0 mapcount:0
mapping:0000000000000000 index:0x0 pfn:0x1060f0
[ 44.602041][ T9507] head: order:3 mapcount:0 entire_mapcount:0
nr_pages_mapped:0 pincount:0
[ 44.602067][ T9507] flags:
0x57ff00000000040(head|node=1|zone=2|lastcpupid=0x7ff)
[ 44.602110][ T9507] page_type: f5(slab)
[ 44.602148][ T9507] raw: 057ff00000000040 ffff88801b042000
dead000000000100 dead000000000122
[ 44.602174][ T9507] raw: 0000000000000000 0000000000080008
00000000f5000000 0000000000000000
[ 44.602202][ T9507] head: 057ff00000000040 ffff88801b042000
dead000000000100 dead000000000122
[ 44.602228][ T9507] head: 0000000000000000 0000000000080008
00000000f5000000 0000000000000000
[ 44.602255][ T9507] head: 057ff00000000003 fffffffffffffe01
00000000ffffffff 00000000ffffffff
[ 44.602280][ T9507] head: ffffffffffffffff 0000000000000000
00000000ffffffff 0000000000000008
[ 44.602296][ T9507] page dumped because: kasan: bad access detected
[ 44.602318][ T9507] page_owner tracks the page as allocated
[ 44.602330][ T9507] page last allocated via order 3, migratetype
Unmovable, gfp_mask
0xd20c0(__GFP_IO|__GFP_FS|__GFP_NOWARN|__GFP_NORETRY|__GFP_COMP|__GFP_NOMEMALLOC),
pid 1, tgid 1 (swapper/0), ts 1751673867
[ 44.602381][ T9507] post_alloc_hook+0x1f9/0x250
[ 44.602412][ T9507] get_page_from_freelist+0x235a/0x23e0
[ 44.602449][ T9507] __alloc_frozen_pages_noprof+0x217/0x5a0
[ 44.602486][ T9507] allocate_slab+0x7d/0x610
[ 44.602511][ T9507] refill_objects+0x2d6/0x350
[ 44.602536][ T9507] __pcs_replace_empty_main+0x2c9/0x6c0
[ 44.602578][ T9507] __kmalloc_cache_noprof+0x3a5/0x610
[ 44.602612][ T9507] container_device_attach+0x8e/0x220
[ 44.602645][ T9507] acpi_bus_attach+0x6fb/0xb90
[ 44.602676][ T9507] device_for_each_child+0x10b/0x1a0
[ 44.602705][ T9507] acpi_dev_for_each_child+0x9b/0xe0
[ 44.602747][ T9507] acpi_bus_attach+0x900/0xb90
[ 44.602777][ T9507] device_for_each_child+0x10b/0x1a0
[ 44.602806][ T9507] acpi_dev_for_each_child+0x9b/0xe0
[ 44.602858][ T9507] acpi_bus_attach+0x900/0xb90
[ 44.602889][ T9507] device_for_each_child+0x10b/0x1a0
[ 44.602919][ T9507] page_owner free stack trace missing
[ 44.602930][ T9507]
[ 44.602938][ T9507] Memory state around the buggy address:
[ 44.602954][ T9507] ffff8881060f5f00: fc fc fc fc fc fc fc fc fc
fc fc fc fc fc fc fc
[ 44.602974][ T9507] ffff8881060f5f80: fc fc fc fc fc fc fc fc fc
fc fc fc fc fc fc fc
[ 44.602994][ T9507] >ffff8881060f6000: fa fb fb fb fb fb fb fb fb
fb fb fb fb fb fb fb
[ 44.603010][ T9507] ^
[ 44.603025][ T9507] ffff8881060f6080: fb fb fb fb fb fb fb fb fb
fb fb fb fb fb fb fb
[ 44.603045][ T9507] ffff8881060f6100: fb fb fb fb fb fb fb fb fb
fb fb fb fb fb fb fb
[ 44.603060][ T9507]
==================================================================
[ 44.603093][ T9507] Kernel panic - not syncing: KASAN: panic_on_warn set ...
[ 44.674986][ T9507] CPU: 1 UID: 0 PID: 9507 Comm: repro Not tainted
7.3.0-rc2-00099-g50d05c7c76c9 #1 PREEMPT(full)
[ 44.675924][ T9507] Hardware name: QEMU Standard PC (Q35 + ICH9,
2009), BIOS 1.17.0-debian-1.17.0-1ubuntu1 04/01/2014
[ 44.676874][ T9507] Call Trace:
[ 44.677180][ T9507] <TASK>
[ 44.677502][ T9507] vpanic+0x56d/0xa60
[ 44.677905][ T9507] ? __pfx_vpanic+0x10/0x10
[ 44.678355][ T9507] panic+0xc5/0xd0
[ 44.678734][ T9507] ? __pfx_panic+0x10/0x10
[ 44.679179][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.679708][ T9507] ? rcu_is_watching+0x16/0xb0
[ 44.680182][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.680682][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.681188][ T9507] check_panic_on_warn+0x89/0xb0
[ 44.681642][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.682159][ T9507] end_report+0x73/0x170
[ 44.682551][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.683122][ T9507] kasan_report+0x128/0x150
[ 44.683540][ T9507] ? __kmalloc_noprof+0x1af/0x720
[ 44.684003][ T9507] ? usx2y_async_seq04_init+0x2b8/0x360
[ 44.684505][ T9507] usx2y_async_seq04_init+0x2b8/0x360
[ 44.684997][ T9507] snd_usx2y_hwdep_dsp_load+0x232/0x5e0
[ 44.685497][ T9507] ? __pfx_snd_usx2y_hwdep_dsp_load+0x10/0x10
[ 44.686053][ T9507] snd_hwdep_ioctl+0x489/0x590
[ 44.686491][ T9507] ? __pfx_snd_usx2y_hwdep_dsp_load+0x10/0x10
[ 44.687041][ T9507] ? __pfx_snd_hwdep_ioctl+0x10/0x10
[ 44.687523][ T9507] ? __fget_files+0x2a/0x420
[ 44.687948][ T9507] ? __fget_files+0x2a/0x420
[ 44.688368][ T9507] ? __fget_files+0x3a0/0x420
[ 44.688797][ T9507] ? __fget_files+0x2a/0x420
[ 44.689223][ T9507] ? bpf_lsm_file_ioctl+0x9/0x20
[ 44.689675][ T9507] ? __pfx_snd_hwdep_ioctl+0x10/0x10
[ 44.690158][ T9507] __se_sys_ioctl+0xfc/0x170
[ 44.690582][ T9507] do_syscall_64+0x155/0x510
[ 44.691011][ T9507] ? trace_irq_disable+0x3b/0x140
[ 44.691470][ T9507] ? entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 44.692021][ T9507] ? clear_bhb_loop+0x30/0x80
[ 44.692465][ T9507] entry_SYSCALL_64_after_hwframe+0x77/0x7f
[ 44.693056][ T9507] RIP: 0033:0x41b46d
[ 44.693415][ T9507] Code: 04 25 28 00 00 00 48 89 45 c8 31 c0 48 8d
45 10 c7 45 b0 10 00 00 00 48 89 45 b8 48 8d 45 d0 48 89 45 c0 b8 10
00 00 00 0f 05 <89> c2 3d 00 f0 ff ff 77 1a 48 8b 45 c8 64 48 2b 04 25
28 00 00 00
[ 44.695144][ T9507] RSP: 002b:00007f916b837100 EFLAGS: 00000246
ORIG_RAX: 0000000000000010
[ 44.695911][ T9507] RAX: ffffffffffffffda RBX: 00007f916b8376c0
RCX: 000000000041b46d
[ 44.696658][ T9507] RDX: 00007f916b837170 RSI: 0000000040604803
RDI: 0000000000000004
[ 44.697402][ T9507] RBP: 00007f916b837150 R08: 0000000000000000
R09: 00007f916b837174
[ 44.698141][ T9507] R10: 0000000000000008 R11: 0000000000000246
R12: 00007f916b8376c0
[ 44.698886][ T9507] R13: 00007fff5766a470 R14: 00007f916b837ce4
R15: 00007fff5766a567
[ 44.699613][ T9507] </TASK>
[ 44.700387][ T9507] Kernel Offset: disabled
[ 44.700934][ T9507] Rebooting in 86400 seconds..
Regards,
[-- Attachment #2: reproducer.c --]
[-- Type: application/octet-stream, Size: 7993 bytes --]
/*
* 248-kasan-slab-use-after-free-read-in-usx2y-async-seq04-init
*/
#define _GNU_SOURCE
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <unistd.h>
#include <linux/usb/ch9.h>
#include <linux/usb/raw_gadget.h>
#define EP0_MAX_PACKET 4096
#define LE16(v) ((v) & 0xff), (((v) >> 8) & 0xff)
#define TASCAM_VENDOR_ID 0x1604
#define TASCAM_US428_ID 0x8001
#define MAX_ALSA_CARDS 8
struct snd_hwdep_dsp_image_abi {
unsigned int index;
unsigned char name[64];
unsigned char *image;
size_t length;
unsigned long driver_data;
};
#define SNDRV_HWDEP_IOCTL_DSP_LOAD 0x40604803u
#define CONTROL_REQUEST_OTHER 0
#define CONTROL_REQUEST_SET_CONFIGURATION 1
#define CONTROL_REQUEST_SET_INTERFACE_ALT1 2
static const struct usb_device_descriptor device_descriptor = {
.bLength = 18,
.bDescriptorType = USB_DT_DEVICE,
.bcdUSB = 0x0200,
.bMaxPacketSize0 = 64,
.idVendor = TASCAM_VENDOR_ID,
.idProduct = TASCAM_US428_ID,
.bcdDevice = 0x0100,
.bNumConfigurations = 1,
};
static const unsigned char config_descriptor[] = {
9, USB_DT_CONFIG, LE16(9 + 9 + 9 + 7), 1, 1, 0, 0xa0, 0xfa,
9, USB_DT_INTERFACE, 0, 0, 0, 0xff, 0xff, 0xff, 0,
9, USB_DT_INTERFACE, 0, 1, 1, 0xff, 0xff, 0xff, 0,
7, USB_DT_ENDPOINT, 0x02, USB_ENDPOINT_XFER_BULK, LE16(512), 0,
};
static int raw_gadget_fd = -1;
static int bulk_out_ep2_handle = -1;
static int hwdep_fd = -1;
static int find_dummy_udc(char *driver_name, size_t driver_len,
char *device_name, size_t device_len)
{
DIR *udc_dir = opendir("/sys/class/udc");
struct dirent *udc_entry;
if (!udc_dir)
return -1;
while ((udc_entry = readdir(udc_dir))) {
char *instance_suffix;
if (udc_entry->d_name[0] == '.')
continue;
snprintf(device_name, device_len, "%s", udc_entry->d_name);
snprintf(driver_name, driver_len, "%s", udc_entry->d_name);
instance_suffix = strrchr(driver_name, '.');
if (instance_suffix)
*instance_suffix = 0;
closedir(udc_dir);
return 0;
}
closedir(udc_dir);
return -1;
}
static int ep0_send_data(const void *data, unsigned int length)
{
unsigned char buffer[sizeof(struct usb_raw_ep_io) + EP0_MAX_PACKET];
struct usb_raw_ep_io *ep0_io = (void *)buffer;
ep0_io->ep = 0;
ep0_io->flags = 0;
ep0_io->length = length;
memcpy(ep0_io->data, data, length);
return ioctl(raw_gadget_fd, USB_RAW_IOCTL_EP0_WRITE, ep0_io);
}
static int ep0_complete_status_stage(unsigned short wLength)
{
unsigned char buffer[sizeof(struct usb_raw_ep_io) + EP0_MAX_PACKET];
struct usb_raw_ep_io *ep0_io = (void *)buffer;
ep0_io->ep = 0;
ep0_io->flags = 0;
ep0_io->length = wLength > EP0_MAX_PACKET ? EP0_MAX_PACKET : wLength;
return ioctl(raw_gadget_fd, USB_RAW_IOCTL_EP0_READ, ep0_io);
}
static void enable_bulk_out_ep2(void)
{
struct usb_endpoint_descriptor endpoint_descriptor = {
.bLength = USB_DT_ENDPOINT_SIZE,
.bDescriptorType = USB_DT_ENDPOINT,
.bEndpointAddress = 0x02,
.bmAttributes = USB_ENDPOINT_XFER_BULK,
.wMaxPacketSize = 512,
};
if (bulk_out_ep2_handle < 0)
bulk_out_ep2_handle = ioctl(raw_gadget_fd,
USB_RAW_IOCTL_EP_ENABLE,
&endpoint_descriptor);
}
static void drain_bulk_out_ep2(void)
{
unsigned char buffer[sizeof(struct usb_raw_ep_io) + 1024];
struct usb_raw_ep_io *ep_io = (void *)buffer;
if (bulk_out_ep2_handle < 0)
return;
ep_io->ep = bulk_out_ep2_handle;
ep_io->flags = 0;
ep_io->length = 512;
ioctl(raw_gadget_fd, USB_RAW_IOCTL_EP_READ, ep_io);
}
static int handle_ep0_control_request(const struct usb_ctrlrequest *control)
{
unsigned char reply[EP0_MAX_PACKET];
int reply_length = -1;
int outcome = CONTROL_REQUEST_OTHER;
if ((control->bRequestType & USB_TYPE_MASK) == USB_TYPE_STANDARD) {
switch (control->bRequest) {
case USB_REQ_GET_DESCRIPTOR:
if ((control->wValue >> 8) == USB_DT_DEVICE) {
reply_length = sizeof(device_descriptor);
memcpy(reply, &device_descriptor, reply_length);
} else if ((control->wValue >> 8) == USB_DT_CONFIG) {
reply_length = sizeof(config_descriptor);
memcpy(reply, config_descriptor, reply_length);
}
break;
case USB_REQ_SET_CONFIGURATION:
ioctl(raw_gadget_fd, USB_RAW_IOCTL_CONFIGURE, 0);
enable_bulk_out_ep2();
reply_length = 0;
outcome = CONTROL_REQUEST_SET_CONFIGURATION;
break;
case USB_REQ_SET_INTERFACE:
reply_length = 0;
if (control->wValue == 1)
outcome = CONTROL_REQUEST_SET_INTERFACE_ALT1;
break;
}
}
if (reply_length < 0) {
ioctl(raw_gadget_fd, USB_RAW_IOCTL_EP0_STALL, 0);
return CONTROL_REQUEST_OTHER;
}
if ((control->bRequestType & USB_DIR_IN) && control->wLength) {
if (reply_length > (int)control->wLength)
reply_length = control->wLength;
ep0_send_data(reply, (unsigned int)reply_length);
} else {
ep0_complete_status_stage(control->wLength);
}
return outcome;
}
static void snapshot_existing_hwdep_nodes(int *hwdep_present_before)
{
for (int card = 0; card < MAX_ALSA_CARDS; card++) {
char path[64];
int fd;
snprintf(path, sizeof(path), "/dev/snd/hwC%dD0", card);
fd = open(path, O_RDONLY);
hwdep_present_before[card] = (fd >= 0);
if (fd >= 0)
close(fd);
}
}
static int open_hwdep_node_created_by_probe(const int *hwdep_present_before)
{
for (int attempt = 0; attempt < 80; attempt++) {
for (int card = 0; card < MAX_ALSA_CARDS; card++) {
char path[64];
int fd;
if (hwdep_present_before[card])
continue;
snprintf(path, sizeof(path), "/dev/snd/hwC%dD0", card);
fd = open(path, O_RDWR);
if (fd >= 0)
return fd;
}
usleep(50000);
}
return -1;
}
static void *dsp_load_thread(void *unused)
{
struct snd_hwdep_dsp_image_abi dsp_image;
unsigned char firmware_bytes[8] = { 0, 1, 2, 3, 4, 5, 6, 7 };
memset(&dsp_image, 0, sizeof(dsp_image));
dsp_image.index = 1;
dsp_image.image = firmware_bytes;
dsp_image.length = sizeof(firmware_bytes);
ioctl(hwdep_fd, SNDRV_HWDEP_IOCTL_DSP_LOAD, &dsp_image);
return NULL;
}
int main(void)
{
char gadget_driver_name[128], udc_device_name[128];
struct usb_raw_init raw_gadget_init;
unsigned char event_buffer[sizeof(struct usb_raw_event) + EP0_MAX_PACKET];
struct usb_raw_event *event = (void *)event_buffer;
int hwdep_present_before[MAX_ALSA_CARDS];
pthread_t loader_thread;
int loader_started = 0;
system("modprobe dummy_hcd 2>/dev/null");
system("modprobe raw_gadget 2>/dev/null");
system("modprobe snd-usb-usx2y 2>/dev/null");
if (find_dummy_udc(gadget_driver_name, sizeof(gadget_driver_name),
udc_device_name, sizeof(udc_device_name)) < 0)
return 1;
snapshot_existing_hwdep_nodes(hwdep_present_before);
raw_gadget_fd = open("/dev/raw-gadget", O_RDWR);
if (raw_gadget_fd < 0)
return 1;
memset(&raw_gadget_init, 0, sizeof(raw_gadget_init));
strncpy((char *)raw_gadget_init.driver_name, gadget_driver_name,
sizeof(raw_gadget_init.driver_name) - 1);
strncpy((char *)raw_gadget_init.device_name, udc_device_name,
sizeof(raw_gadget_init.device_name) - 1);
raw_gadget_init.speed = USB_SPEED_HIGH;
if (ioctl(raw_gadget_fd, USB_RAW_IOCTL_INIT, &raw_gadget_init) < 0)
return 1;
if (ioctl(raw_gadget_fd, USB_RAW_IOCTL_RUN, 0) < 0)
return 1;
for (;;) {
int outcome;
event->type = 0;
event->length = EP0_MAX_PACKET;
if (ioctl(raw_gadget_fd, USB_RAW_IOCTL_EVENT_FETCH, event) < 0)
return 1;
if (event->type != USB_RAW_EVENT_CONTROL)
continue;
outcome = handle_ep0_control_request(
(struct usb_ctrlrequest *)event->data);
if (outcome == CONTROL_REQUEST_SET_CONFIGURATION && !loader_started) {
hwdep_fd = open_hwdep_node_created_by_probe(hwdep_present_before);
if (hwdep_fd < 0)
return 1;
pthread_create(&loader_thread, NULL, dsp_load_thread, NULL);
loader_started = 1;
}
if (outcome == CONTROL_REQUEST_SET_INTERFACE_ALT1) {
drain_bulk_out_ep2();
usleep(120000);
break;
}
}
close(raw_gadget_fd);
if (loader_started)
pthread_join(loader_thread, NULL);
return 0;
}
^ permalink raw reply [flat|nested] 2+ messages in thread
* Re: [BUG] KASAN: slab-use-after-free Read in usx2y_async_seq04_init
2026-09-11 15:53 [BUG] KASAN: slab-use-after-free Read in usx2y_async_seq04_init Farhad Alemi
@ 2026-09-12 12:34 ` Takashi Iwai
0 siblings, 0 replies; 2+ messages in thread
From: Takashi Iwai @ 2026-09-12 12:34 UTC (permalink / raw)
To: Farhad Alemi; +Cc: Jaroslav Kysela, Takashi Iwai, linux-sound, linux-kernel
On Fri, 11 Sep 2026 17:53:55 +0200,
Farhad Alemi wrote:
>
> Hello,
>
> We are reporting the following crash (reproducer attached):
> Linux version 7.3.0-rc2 50d05c7c76c96b90462f24debacca971d2e86713
> Build Config: UpstreamAppArmorKASAN (KASAN + UBSAN, panic_on_warn=1)
>
> [ 44.599577][ T9507] BUG: KASAN: slab-use-after-free in
> usx2y_async_seq04_init+0x2b8/0x360
(snip)
Both this one and your another report ("[BUG] KASAN:
slab-use-after-free Read in __snd_ctl_add_replace") are basically the
same issue -- UAFs after the card release of USB drivers that are done
asynchronously from the disconnect callback.
Below is the fix patch for both.
thanks,
Takashi
-- 8< --
From: Takashi Iwai <tiwai@suse.de>
Subject: [PATCH] ALSA: core: Fix potential UAF after asynchronous card release
Usually a sound driver releases the resources assigned to the card via
snd_card_free(), and it synchronizes with the whole release procedure.
However, when the card is released asynchronously via
snd_card_free_when_closed() like USB-audio driver, the situation is
slightly different; although the snd_card_disconnect() call at the
disconnection guarantees that any newer accesses will be gated, the
in-flight tasks might be still accessing to the underlying card->dev
device even after the disconnection, which would cause a
use-after-free in the end, as reported by fuzzers.
For addressing the bug above, this patch takes the refcount of
card->dev at initialization of the card object, and releases at its
destructor. This assures the availability of the card->dev in its
whole lifecycle.
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Closes: https://lore.kernel.org/CA+0ovChexj4TrZL_2iG_P0WBEbZc5+73GfB3DkciQi=R8pZOnA@mail.gmail.com
Closes: https://lore.kernel.org/CA+0ovCgQUQNN=Z1tJTouiCsDaXR5M-3-SQEGk-cpPXQkM5Xh+w@mail.gmail.com
Cc: <stable@vger.kernel.org>
Signed-off-by: Takashi Iwai <tiwai@suse.de>
---
sound/core/init.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/sound/core/init.c b/sound/core/init.c
index 2f7f83a7611b..bffa94b7b956 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -310,7 +310,7 @@ static int snd_card_init(struct snd_card *card, struct device *parent,
kfree(card); /* manually free here, as no destructor called */
return err;
}
- card->dev = parent;
+ card->dev = get_device(parent);
card->number = idx;
WARN_ON(IS_MODULE(CONFIG_SND) && !module);
card->module = module;
@@ -605,6 +605,7 @@ static int snd_card_do_free(struct snd_card *card)
}
if (card->release_completion)
complete(card->release_completion);
+ put_device(card->dev);
if (!managed)
kfree(card);
return 0;
--
2.55.0
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-09-12 12:34 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-09-11 15:53 [BUG] KASAN: slab-use-after-free Read in usx2y_async_seq04_init Farhad Alemi
2026-09-12 12:34 ` Takashi Iwai
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®