Messages in this thread Patch in this message | | | Date | Thu, 29 Nov 2007 13:09:53 -0500 | From | Mark Lord <> | Subject | [PATCH] base/class.c: prevent ooops due to insert/remove race (v3) |
| |
Mark Lord wrote: > Mark Lord wrote: >> Mark Lord wrote: >> ... >> And here is a "prevented" oops, courtesy of the patch (2.6.23.8). >> These are easy to reproduce (just jiggle the connection on an >> attached USB multi-card reader with a CF card inserted): > ... >> [ 347.099562] usb 5-6: USB disconnect, address 10 >> [ 347.101077] BUG: unable to handle kernel NULL pointer dereference >> at virtual address 00000000 > > ... > > > Mmmm.. that's odd. It *did* Oops there. I wonder how/why ? ...
Ahh.. it was the *other* call to strlen() that was crapping out. Here's an updated patch to prevent the Oops:
* * * *
While doing insert/remove (quickly) tests on USB, I managed to trigger an Oops on 2.6.23.8 on a call to strlen() in make_class_name().
USB maintainers can try this themselves, by plugging in an external USB XX-in-1 flash reader, with a CF card inserted. Then just jiggle the connection so that the device connects and disconnects rapidly. This may not sound realistic, but there's definitely a race in there, and this is a quick way to reproduce it if need be.
The patch below prevents the oops, but still keeps the bug visible.
Signed-off-by: Mark Lord <mlord@pobox.com> ---
Patch applies to both 2.6.24 and 2.6.23.
--- old/drivers/base/class.c 2007-11-29 10:51:43.000000000 -0500 +++ linux/drivers/base/class.c 2007-11-29 13:00:15.000000000 -0500 @@ -352,9 +352,22 @@ char *make_class_name(const char *name, struct kobject *kobj) { char *class_name; + const char *kname; int size; - size = strlen(name) + strlen(kobject_name(kobj)) + 2; + /* Rapidly inserting/removing a USB device (others?) + * can trigger an Oops on the strlen() call. + * Cause unknown yet, so prevent the Oops + * but don't mask the issue. + */ + kname = kobject_name(kobj); + if (!kname || !name) { + printk(KERN_ERR "make_class_name: name=%p kname=%p\n", + name, kname); + BUG_ON(1); + return NULL; + } + size = strlen(name) + strlen(kname) + 2; class_name = kmalloc(size, GFP_KERNEL); if (!class_name) - To unsubscribe from this list: send the line "unsubscribe linux-kernel" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html Please read the FAQ at http://www.tux.org/lkml/
| |