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 <sven@narfation.org>
This commit is contained in:
Sven Eckelmann 2017-12-20 11:16:13 +01:00 committed by Jan-Philipp Litza
parent c9eccb9c47
commit 779f17af89
No known key found for this signature in database
GPG Key ID: 1FB658053CE27196

View File

@ -92,6 +92,11 @@
#define foreach(item, list) \ #define foreach(item, list) \
for(item = list; item != NULL; item = item->next) 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 {
struct router *next; struct router *next;
macaddr_t src; macaddr_t src;
@ -295,9 +300,10 @@ check_failed:
static void expire_routers() { static void expire_routers() {
struct router **prev_ptr = &G.routers; struct router **prev_ptr = &G.routers;
struct router *router; struct router *router;
struct router *safe;
time_t now = time(NULL); time_t now = time(NULL);
foreach(router, G.routers) { foreach_safe(router, safe, G.routers) {
if (router->eol < now) { if (router->eol < now) {
DEBUG_MSG("router " F_MAC " expired", F_MAC_VAR(router->src)); DEBUG_MSG("router " F_MAC " expired", F_MAC_VAR(router->src));
*prev_ptr = router->next; *prev_ptr = router->next;