From: "Zephaniah E. Hull" While trying to figure out the best way to handle an odd mouse, I found that we oopsed when doing a rmmod on usbhid while someone had a USB device open through evdev. We try to loop through evdev->list, calling kill_fasync on each member, however by the time we try to get the next pointer, we have already freed the member and poisoned the next/last. akpm: doesn't really fix the bug (lack of locking). But I'm queueing it up so I can nag Dmitry with it ;) Signed-off-by: "Zephaniah E. Hull" Cc: Dmitry Torokhov Signed-off-by: Andrew Morton --- drivers/input/evdev.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff -puN drivers/input/evdev.c~crash-on-evdev-disconnect drivers/input/evdev.c --- a/drivers/input/evdev.c~crash-on-evdev-disconnect +++ a/drivers/input/evdev.c @@ -659,7 +659,7 @@ static struct input_handle *evdev_connec static void evdev_disconnect(struct input_handle *handle) { struct evdev *evdev = handle->private; - struct evdev_list *list; + struct evdev_list *list, *next; sysfs_remove_link(&input_class.subsys.kset.kobj, evdev->name); class_device_destroy(&input_class, @@ -670,7 +670,7 @@ static void evdev_disconnect(struct inpu input_flush_device(handle, NULL); input_close_device(handle); wake_up_interruptible(&evdev->wait); - list_for_each_entry(list, &evdev->list, node) + list_for_each_entry_safe(list, next, &evdev->list, node) kill_fasync(&list->fasync, SIGIO, POLL_HUP); } else evdev_free(evdev); _