From 779f17af897df24a8e577bf0a863d824dd625c05 Mon Sep 17 00:00:00 2001 From: Sven Eckelmann Date: Wed, 20 Dec 2017 11:16:13 +0100 Subject: [PATCH] gluon-radv-filterd: Fix use-after-free in expire_routers The macro foreach is dereferencing router to get the next node in list. This even happens when the node was just freed in the last iteration (and thus could crash the program). To avoid this crash, the next pointer has to be saved before the node is freed. Signed-off-by: Sven Eckelmann --- package/gluon-radv-filterd/src/gluon-radv-filterd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/package/gluon-radv-filterd/src/gluon-radv-filterd.c b/package/gluon-radv-filterd/src/gluon-radv-filterd.c index 3aae38d0..0fbcb1cf 100644 --- a/package/gluon-radv-filterd/src/gluon-radv-filterd.c +++ b/package/gluon-radv-filterd/src/gluon-radv-filterd.c @@ -92,6 +92,11 @@ #define foreach(item, list) \ for(item = list; item != NULL; item = item->next) +#define foreach_safe(item, safe, list) \ + for (item = (list); \ + (item) && (((safe) = item->next) || 1); \ + item = safe) + struct router { struct router *next; macaddr_t src; @@ -295,9 +300,10 @@ check_failed: static void expire_routers() { struct router **prev_ptr = &G.routers; struct router *router; + struct router *safe; time_t now = time(NULL); - foreach(router, G.routers) { + foreach_safe(router, safe, G.routers) { if (router->eol < now) { DEBUG_MSG("router " F_MAC " expired", F_MAC_VAR(router->src)); *prev_ptr = router->next;