From c0c8034bc17519c7960f40f6d796b5485cfc4cdb Mon Sep 17 00:00:00 2001 From: Hans Dedecker Date: Tue, 14 May 2019 16:18:51 +0200 Subject: [PATCH] treewide: init assignment lists head When allocating an assignment in alloc_assignment; init the circular head and lease_list circular lists. Avoids checking NULL pointer when freeing the assignment in free_assignment. Signed-off-by: Hans Dedecker --- src/dhcpv4.c | 6 +++--- src/dhcpv6-ia.c | 8 ++++---- src/odhcpd.h | 20 +++++++++++++++----- 3 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/dhcpv4.c b/src/dhcpv4.c index 9d21423..2634f65 100644 --- a/src/dhcpv4.c +++ b/src/dhcpv4.c @@ -1024,9 +1024,9 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac, if (!a) { if (!iface->no_dynamic_dhcp || l) { /* Create new binding */ - a = calloc(1, sizeof(*a)); + a = alloc_assignment(0); if (!a) { - syslog(LOG_ERR, "Failed to calloc binding on interface %s", + syslog(LOG_ERR, "Failed to alloc assignment on interface %s", iface->ifname); return NULL; } @@ -1057,7 +1057,7 @@ dhcpv4_lease(struct interface *iface, enum dhcpv4_msg msg, const uint8_t *mac, } else if (((a->addr & iface->dhcpv4_mask.s_addr) != (iface->dhcpv4_start_ip.s_addr & iface->dhcpv4_mask.s_addr)) && !(a->flags & OAF_STATIC)) { - list_del(&a->head); + list_del_init(&a->head); a->addr = INADDR_ANY; assigned = dhcpv4_assign(iface, a, reqaddr); diff --git a/src/dhcpv6-ia.c b/src/dhcpv6-ia.c index 81c2481..9559b96 100644 --- a/src/dhcpv6-ia.c +++ b/src/dhcpv6-ia.c @@ -75,10 +75,10 @@ int dhcpv6_ia_setup_interface(struct interface *iface, bool enable) struct dhcp_assignment *border; if (list_empty(&iface->ia_assignments)) { - border = calloc(1, sizeof(*border)); + border = alloc_assignment(0); if (!border) { - syslog(LOG_ERR, "Calloc failed for border on %s", iface->name); + syslog(LOG_ERR, "Failed to alloc border on %s", iface->name); return -1; } @@ -719,7 +719,7 @@ static void handle_addrlist_change(struct netevent_handler_info *info) while (!list_empty(&reassign)) { c = list_first_entry(&reassign, struct dhcp_assignment, head); - list_del(&c->head); + list_del_init(&c->head); if (!assign_pd(iface, c)) { c->assigned = 0; list_add(&c->head, &iface->ia_assignments); @@ -1237,7 +1237,7 @@ ssize_t dhcpv6_ia_handle_IAs(uint8_t *buf, size_t buflen, struct interface *ifac if ((!iface->no_dynamic_dhcp || (l && is_na)) && (iface->dhcpv6_pd || iface->dhcpv6_na)) { /* Create new binding */ - a = calloc(1, sizeof(*a) + clid_len); + a = alloc_assignment(clid_len); if (a) { a->clid_len = clid_len; diff --git a/src/odhcpd.h b/src/odhcpd.h index 9535e75..37a5a4a 100644 --- a/src/odhcpd.h +++ b/src/odhcpd.h @@ -309,11 +309,8 @@ extern struct avl_tree interfaces; inline static void free_assignment(struct dhcp_assignment *a) { - if (a->head.next) - list_del(&a->head); - - if (a->lease_list.next) - list_del(&a->lease_list); + list_del(&a->head); + list_del(&a->lease_list); if (a->dhcp_free_cb) a->dhcp_free_cb(a); @@ -323,6 +320,19 @@ inline static void free_assignment(struct dhcp_assignment *a) free(a); } +inline static struct dhcp_assignment *alloc_assignment(size_t extra_len) +{ + struct dhcp_assignment *a = calloc(1, sizeof(*a) + extra_len); + + if (!a) + return NULL; + + INIT_LIST_HEAD(&a->head); + INIT_LIST_HEAD(&a->lease_list); + + return a; +} + // Exported main functions int odhcpd_register(struct odhcpd_event *event); int odhcpd_deregister(struct odhcpd_event *event); -- 2.25.1