treewide: init assignment lists head
authorHans Dedecker <dedeckeh@gmail.com>
Tue, 14 May 2019 14:18:51 +0000 (16:18 +0200)
committerHans Dedecker <dedeckeh@gmail.com>
Wed, 15 May 2019 08:10:08 +0000 (10:10 +0200)
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 <dedeckeh@gmail.com>
src/dhcpv4.c
src/dhcpv6-ia.c
src/odhcpd.h

index 9d214234563a46f2b21612f2cd9910e13b794650..2634f65a69e997c5292c7c7f3679709c45cf62d4 100644 (file)
@@ -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);
index 81c2481aef40787f5bfaf32c7438bbe44ef62fd3..9559b9655a9ce4e26d49cbedd0429687919da02c 100644 (file)
@@ -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;
index 9535e752a12c61d3f2a61323757a301e90f32916..37a5a4a4c6e448683f7f4daae924e3d84b983059 100644 (file)
@@ -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);