Re: crash by cdc_acm driver in kernels 4.8-rc1/5

From: Oliver Neukum
Date: Wed Sep 28 2016 - 05:16:20 EST


On Tue, 2016-09-27 at 18:34 +0200, Wim Osterholt wrote:
> On Thu, Sep 22, 2016 at 04:40:50PM +0200, Oliver Neukum wrote:
> >
> > dmesg -c
> > echo 9 > /proc/sysrq-trigger
> > modprobe cdc_acm
> > echo "module cdc_acm +mpf" > /sys/kernel/debug/dynamic_debug/control
> >
> > [plug your device in]
> >
> > and provide the full output of dmesg after that.
>
> After some experimenting I succeeded in grabbing it over the serial port.
> The console was immedately frozen, but the serial port kept working:

Very good. This is a valid oops. We can do two things. When I
decode it, seems to crash in acm_alloc_minor() which does not make
sense. It is likely that our kernels or compilers are a bit different.
Could you please call gdb on your kernel module cdc-acm.ko
and do:

list *(acm_probe+0x4ee)

this should show you where it crashes. In addition I've attached
a patch with paranoid debugging. Could you compile and test a kernel
with it?

Regards
Oliver

From 28bb525ab295bd014768868eafb6a76d0c0d80c2 Mon Sep 17 00:00:00 2001
From: Oliver Neukum <oneukum@xxxxxxxx>
Date: Wed, 28 Sep 2016 11:11:04 +0200
Subject: [PATCH] CDC-ACM: more paranoid debugging

---
drivers/usb/class/cdc-acm.c | 4 ++++
1 file changed, 4 insertions(+)

diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 78f0f85..283e16e 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -1324,10 +1324,13 @@ made_compressed_probe:
if (minor < 0)
goto alloc_fail1;

+ WARN_ON(!epctrl);
ctrlsize = usb_endpoint_maxp(epctrl);
+ WARN_ON(!epread);
readsize = usb_endpoint_maxp(epread) *
(quirks == SINGLE_RX_URB ? 1 : 2);
acm->combined_interfaces = combined_interfaces;
+ WARN_ON(!epwrite);
acm->writesize = usb_endpoint_maxp(epwrite) * 20;
acm->control = control_interface;
acm->data = data_interface;
@@ -1352,6 +1355,7 @@ made_compressed_probe:
acm->port.ops = &acm_port_ops;
init_usb_anchor(&acm->delayed);
acm->quirks = quirks;
+ dev_dbg(&intf->dev, "control structures set up\n");

buf = usb_alloc_coherent(usb_dev, ctrlsize, GFP_KERNEL, &acm->ctrl_dma);
if (!buf)
--
2.6.2