Re: [syzbot] [usb?] KASAN: slab-use-after-free Write in usb_free_urb

From: Edward Adam Davis

Date: Wed Sep 02 2026 - 23:29:08 EST


From: Edward Aadm Davis <eadavis@xxxxxxxx>

#syz test: upstream 786262be6048

diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index a16e59248480..138b58914f1c 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -192,8 +192,8 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb)
break;
}

- cdev->ep1_in_urb.actual_length = 0;
- ret = usb_submit_urb(&cdev->ep1_in_urb, GFP_ATOMIC);
+ cdev->ep1_in_urb->actual_length = 0;
+ ret = usb_submit_urb(cdev->ep1_in_urb, GFP_ATOMIC);
if (ret < 0)
dev_err(dev, "unable to submit urb. OOM!?\n");
}
@@ -408,6 +408,8 @@ static void card_free(struct snd_card *card)
#endif
snd_usb_caiaq_audio_free(cdev);
usb_put_dev(cdev->chip.dev);
+ usb_free_urb(cdev->ep1_in_urb);
+ cdev->ep1_in_urb = NULL;
}

static int create_card(struct usb_device *usb_dev,
@@ -457,10 +459,11 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
return -EIO;
}

- usb_init_urb(&cdev->ep1_in_urb);
+ cdev->ep1_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ usb_init_urb(cdev->ep1_in_urb);
usb_init_urb(&cdev->midi_out_urb);

- usb_fill_bulk_urb(&cdev->ep1_in_urb, usb_dev,
+ usb_fill_bulk_urb(cdev->ep1_in_urb, usb_dev,
usb_rcvbulkpipe(usb_dev, 0x1),
cdev->ep1_in_buf, EP1_BUFSIZE,
usb_ep1_command_reply_dispatch, cdev);
@@ -471,7 +474,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
snd_usb_caiaq_midi_output_done, cdev);

/* sanity checks of EPs before actually submitting */
- if (usb_urb_ep_type_check(&cdev->ep1_in_urb) ||
+ if (usb_urb_ep_type_check(cdev->ep1_in_urb) ||
usb_urb_ep_type_check(&cdev->midi_out_urb)) {
dev_err(dev, "invalid EPs\n");
return -EINVAL;
@@ -480,7 +483,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
init_waitqueue_head(&cdev->ep1_wait_queue);
init_waitqueue_head(&cdev->prepare_wait_queue);

- if (usb_submit_urb(&cdev->ep1_in_urb, GFP_KERNEL) != 0)
+ if (usb_submit_urb(cdev->ep1_in_urb, GFP_KERNEL) != 0)
return -EIO;

err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
@@ -530,7 +533,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
return 0;

err_kill_urb:
- usb_kill_urb(&cdev->ep1_in_urb);
+ usb_kill_urb(cdev->ep1_in_urb);
return err;
}

@@ -576,7 +579,7 @@ static void snd_disconnect(struct usb_interface *intf)
#endif
snd_usb_caiaq_audio_disconnect(cdev);

- usb_kill_urb(&cdev->ep1_in_urb);
+ usb_kill_urb(cdev->ep1_in_urb);
usb_kill_urb(&cdev->midi_out_urb);

snd_card_free_when_closed(card);
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index 743eb0387b5f..a5f7dada25d8 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -60,7 +60,7 @@ struct snd_usb_caiaq_cb_info;
struct snd_usb_caiaqdev {
struct snd_usb_audio chip;

- struct urb ep1_in_urb;
+ struct urb *ep1_in_urb;
struct urb midi_out_urb;
struct urb **data_urbs_in;
struct urb **data_urbs_out;