Skip to content

Commit f7744fa

Browse files
anirudhrbJiri Kosina
authored andcommitted
HID: usbhid: free raw_report buffers in usbhid_stop
Free the unsent raw_report buffers when the device is removed. Fixes a memory leak reported by syzbot at: https://syzkaller.appspot.com/bug?id=7b4fa7cb1a7c2d3342a2a8a6c53371c8c418ab47 Reported-by: syzbot+47b26cd837ececfc666d@syzkaller.appspotmail.com Tested-by: syzbot+47b26cd837ececfc666d@syzkaller.appspotmail.com Signed-off-by: Anirudh Rayabharam <mail@anirudhrb.com> Signed-off-by: Jiri Kosina <jkosina@suse.cz>
1 parent f4abaa9 commit f7744fa

1 file changed

Lines changed: 12 additions & 1 deletion

File tree

drivers/hid/usbhid/hid-core.c

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -505,7 +505,7 @@ static void hid_ctrl(struct urb *urb)
505505

506506
if (unplug) {
507507
usbhid->ctrltail = usbhid->ctrlhead;
508-
} else {
508+
} else if (usbhid->ctrlhead != usbhid->ctrltail) {
509509
usbhid->ctrltail = (usbhid->ctrltail + 1) & (HID_CONTROL_FIFO_SIZE - 1);
510510

511511
if (usbhid->ctrlhead != usbhid->ctrltail &&
@@ -1223,9 +1223,20 @@ static void usbhid_stop(struct hid_device *hid)
12231223
mutex_lock(&usbhid->mutex);
12241224

12251225
clear_bit(HID_STARTED, &usbhid->iofl);
1226+
12261227
spin_lock_irq(&usbhid->lock); /* Sync with error and led handlers */
12271228
set_bit(HID_DISCONNECTED, &usbhid->iofl);
1229+
while (usbhid->ctrltail != usbhid->ctrlhead) {
1230+
if (usbhid->ctrl[usbhid->ctrltail].dir == USB_DIR_OUT) {
1231+
kfree(usbhid->ctrl[usbhid->ctrltail].raw_report);
1232+
usbhid->ctrl[usbhid->ctrltail].raw_report = NULL;
1233+
}
1234+
1235+
usbhid->ctrltail = (usbhid->ctrltail + 1) &
1236+
(HID_CONTROL_FIFO_SIZE - 1);
1237+
}
12281238
spin_unlock_irq(&usbhid->lock);
1239+
12291240
usb_kill_urb(usbhid->urbin);
12301241
usb_kill_urb(usbhid->urbout);
12311242
usb_kill_urb(usbhid->urbctrl);

0 commit comments

Comments
 (0)