Messages in this thread Patch in this message | | | From | Dmitry Torokhov <> | Subject | [PATCH 2.6] 2/3 Serio: possible race in handle_events | Date | Sat, 23 Aug 2003 01:31:45 -0500 |
| |
The event handling in serio is racy because serio_handle_events does not check whether serio in event list is still alive or has already been freed. One possible solution is to check whether serio in question is still registered in serio_list and skip events referring to unknown serios.
Dmitry
diff -urN --exclude-from=/usr/src/exclude 2.6.0-test4/drivers/input/serio/serio.c linux-2.6.0-test4/drivers/input/serio/serio.c --- 2.6.0-test4/drivers/input/serio/serio.c 2003-08-22 23:26:50.000000000 -0500 +++ linux-2.6.0-test4/drivers/input/serio/serio.c 2003-08-22 23:25:20.000000000 -0500 @@ -85,6 +85,16 @@ static DECLARE_WAIT_QUEUE_HEAD(serio_wait); static DECLARE_COMPLETION(serio_exited); +static int is_known_serio(struct serio *serio) +{ + struct serio *s; + + list_for_each_entry(s, &serio_list, node) + if (s == serio) + return 1; + return 0; +} + void serio_handle_events(void) { struct list_head *node, *next; @@ -93,17 +103,21 @@ list_for_each_safe(node, next, &serio_event_list) { event = container_of(node, struct serio_event, node); + down(&serio_sem); + if (!is_known_serio(event->serio)) + goto event_done; + switch (event->type) { case SERIO_RESCAN : - down(&serio_sem); if (event->serio->dev && event->serio->dev->disconnect) event->serio->dev->disconnect(event->serio); serio_find_dev(event->serio); - up(&serio_sem); break; default: break; } +event_done: + up(&serio_sem); list_del_init(node); kfree(event); } - 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/
| |