Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

usb: cdc-wdm: resp_count can be 0 even if WDM_READ is set

Do not decrement resp_count if it's already 0.

We set resp_count to 0 when the device is closed. The next open and
read will try to clear the WDM_READ flag if there was leftover data
in the read buffer. This fix is necessary to prevent resubmitting
the read URB in a tight loop because resp_count becomes negative.

The bug can easily be triggered from userspace by not reading all
data in the read buffer, and then closing and reopening the chardev.

Fixes: 8dd5cd5395b9 ("usb: cdc-wdm: avoid hanging on zero length reads")
Cc: <stable@vger.kernel.org> # 3.13
Signed-off-by: Bjørn Mork <bjorn@mork.no>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>

authored by

Bjørn Mork and committed by
Greg Kroah-Hartman
f563926f 52a6966c

+1 -1
+1 -1
drivers/usb/class/cdc-wdm.c
··· 445 445 clear_bit(WDM_READ, &desc->flags); 446 446 447 447 /* submit read urb only if the device is waiting for it */ 448 - if (!--desc->resp_count) 448 + if (!desc->resp_count || !--desc->resp_count) 449 449 goto out; 450 450 451 451 set_bit(WDM_RESPONDING, &desc->flags);