]> git.ipfire.org Git - thirdparty/lldpd.git/commitdiff
daemon: avoid double-free when bond is converted to another type master
authorVincent Bernat <vincent@bernat.ch>
Sat, 13 Jun 2026 08:11:33 +0000 (10:11 +0200)
committerVincent Bernat <vincent@bernat.ch>
Sat, 13 Jun 2026 08:11:33 +0000 (10:11 +0200)
See https://github.com/lldpd/lldpd/commit/08f9c680f9b386a34a9d7940bdb85936449738b4#commitcomment-188359666.

src/daemon/interfaces-linux.c

index 9b612eeb0f94516543608daf69257120c2708f44..73670b00844b86981e3bdab043367dd9eeb571df 100644 (file)
@@ -934,8 +934,10 @@ iflinux_handle_bond(struct lldpd *cfg, struct interfaces_device_list *interfaces
                                log_debug("interfaces",
                                    "bond %s is converted from another type of interface",
                                    hardware->h_ifname);
                                log_debug("interfaces",
                                    "bond %s is converted from another type of interface",
                                    hardware->h_ifname);
-                               if (hardware->h_ops && hardware->h_ops->cleanup)
+                               if (hardware->h_ops && hardware->h_ops->cleanup) {
                                        hardware->h_ops->cleanup(cfg, hardware);
                                        hardware->h_ops->cleanup(cfg, hardware);
+                                       hardware->h_ops = NULL;
+                               }
                                levent_hardware_release(hardware);
                                levent_hardware_init(hardware);
                        }
                                levent_hardware_release(hardware);
                                levent_hardware_init(hardware);
                        }
@@ -943,7 +945,7 @@ iflinux_handle_bond(struct lldpd *cfg, struct interfaces_device_list *interfaces
                            calloc(1, sizeof(struct bond_master));
                        if (!bmaster) {
                                log_warn("interfaces", "not enough memory");
                            calloc(1, sizeof(struct bond_master));
                        if (!bmaster) {
                                log_warn("interfaces", "not enough memory");
-                               lldpd_hardware_cleanup(cfg, hardware);
+                               if (created) lldpd_hardware_cleanup(cfg, hardware);
                                continue;
                        }
                } else
                                continue;
                        }
                } else
@@ -954,7 +956,7 @@ iflinux_handle_bond(struct lldpd *cfg, struct interfaces_device_list *interfaces
                        if (iface_bond_init(cfg, hardware) != 0) {
                                log_warn("interfaces", "unable to initialize %s",
                                    hardware->h_ifname);
                        if (iface_bond_init(cfg, hardware) != 0) {
                                log_warn("interfaces", "unable to initialize %s",
                                    hardware->h_ifname);
-                               lldpd_hardware_cleanup(cfg, hardware);
+                               if (created) lldpd_hardware_cleanup(cfg, hardware);
                                continue;
                        }
                        hardware->h_ops = &bond_ops;
                                continue;
                        }
                        hardware->h_ops = &bond_ops;