]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
lib: fix a segfault introduced in ef3707 when freeing an atom
authorVincent Bernat <bernat@luffy.cx>
Sat, 12 Oct 2013 15:29:26 +0000 (17:29 +0200)
committerVincent Bernat <bernat@luffy.cx>
Sat, 12 Oct 2013 15:29:26 +0000 (17:29 +0200)
In the change "lldpd: make notifications work when a port goes down",
a regression was introduced. It is important to never call
`TAILQ_REMOVE` on a marshalled struct, like when we are in
liblldpctl. This is because the marshalling process does not keep a
real list (prev pointer is incorrect).

The change ef3707 did introduce a regression by calling TAILQ_REMOVE
in a case where it is useless. We only need to call TAILQ_REMOVE if we
won't empty the whole list. So when we call `lldpd_remote_cleanup()`
with `all` set to `1`, we don't need to call TAILQ_REMOVE.

src/lldpd-structs.c

index 5c907f0df151fd3a288c4136e94cc686c1900ac4..12fe3b816f55d4dcd2f3ba6f8982d45970a48514 100644 (file)
@@ -131,7 +131,11 @@ lldpd_remote_cleanup(struct lldpd_hardware *hardware,
                }
                if (del) {
                        if (expire) expire(hardware, port);
-                       TAILQ_REMOVE(&hardware->h_rports, port, p_entries);
+                       /* This TAILQ_REMOVE is dangerous. It should not be
+                        * called while in liblldpctl because we don't have a
+                        * real list. It is only needed to be called when we
+                        * don't delete the entire list. */
+                       if (!all) TAILQ_REMOVE(&hardware->h_rports, port, p_entries);
                        lldpd_port_cleanup(port, 1);
                        free(port);
                }