lkml.org 
[lkml]   [2003]   [Aug]   [23]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
From
Subject[PATCH 2.6] 2/3 Serio: possible race in handle_events
Date
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/
\
 
 \ /
  Last update: 2005-03-22 13:48    [W:0.251 / U:0.484 seconds]
©2003-2014 Jasper Spaans. Advertise on this site