]> git.ipfire.org Git - thirdparty/bird.git/commitdiff
Fixes nasty bug in event processing.
authorOndrej Zajicek <santiago@crfreenet.org>
Thu, 18 Dec 2008 22:26:08 +0000 (23:26 +0100)
committerOndrej Zajicek <santiago@crfreenet.org>
Thu, 18 Dec 2008 22:26:08 +0000 (23:26 +0100)
WALK_LIST_DELSAFE (in ev_run_list) is not safe with regard
to deletion of next node. When some events are rescheduled
during event execution, it may lead to deletion of next
node and some events are skipped. Such skipped nodes remain
in temporary list on stack and the last of them contains
'next' pointer to stack area. When this event is later
scheduled, it damages stack area trying to remove it from
the list, which leads to random crashes with funny
backtraces :-) .

lib/event.c
lib/lists.h

index 9b5870d33c40c6742b2b513cbcd82a50bd28923d..55a9c4872539223ce3ee423f159d015dceb65cc1 100644 (file)
@@ -125,13 +125,13 @@ ev_schedule(event *e)
 int
 ev_run_list(event_list *l)
 {
-  node *n, *p;
+  node *n;
   list tmp_list;
 
   init_list(&tmp_list);
   add_tail_list(&tmp_list, l);
   init_list(l);
-  WALK_LIST_DELSAFE(n, p, tmp_list)
+  WALK_LIST_FIRST(n, tmp_list)
     {
       event *e = SKIP_BACK(event, n, n);
       ev_run(e);
index 5b36ec83e7bbab008a2c231e406d473fcf856b51..342dfd62b4f1f86cbd28cd114e945ff3de91e84f 100644 (file)
@@ -37,6 +37,9 @@ typedef struct list {                 /* In fact two overlayed nodes */
                                n=(void *)((NODE (n))->next))
 #define WALK_LIST_DELSAFE(n,nxt,list) \
      for(n=HEAD(list); nxt=(void *)((NODE (n))->next); n=(void *) nxt)
+/* WALK_LIST_FIRST supposes that called code removes each processed node */
+#define WALK_LIST_FIRST(n,list) \
+     while(n=HEAD(list), (NODE (n))->next)
 #define WALK_LIST_BACKWARDS(n,list) for(n=TAIL(list);(NODE (n))->prev; \
                                n=(void *)((NODE (n))->prev))
 #define WALK_LIST_BACKWARDS_DELSAFE(n,prv,list) \