]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
arp: fix memory leak
authorRoy Marples <roy@marples.name>
Tue, 24 Oct 2017 23:23:29 +0000 (00:23 +0100)
committerRoy Marples <roy@marples.name>
Tue, 24 Oct 2017 23:23:29 +0000 (00:23 +0100)
Prior patch introduced a memory leak if a new ARP state was
added after BPF_FREE was set. Cater for this.

src/arp.c

index 61a8c771e79a6041835d133d008a1852b763f548..372978f2da17c12e08585d439c61d823bc67c09e 100644 (file)
--- a/src/arp.c
+++ b/src/arp.c
@@ -185,6 +185,27 @@ arp_close(struct interface *ifp)
        }
 }
 
+static void
+arp_tryfree(struct interface *ifp)
+{
+       struct iarp_state *state = ARP_STATE(ifp);
+
+       /* If there are no more ARP states, close the socket. */
+       if (TAILQ_FIRST(&state->arp_states) == NULL) {
+               arp_close(ifp);
+               if (state->bpf_flags & BPF_READING)
+                       state->bpf_flags |= BPF_EOF | BPF_FREE;
+               else {
+                       free(state);
+                       ifp->if_data[IF_DATA_ARP] = NULL;
+               }
+       } else {
+               state->bpf_flags &= BPF_FREE;
+               if (bpf_arp(ifp, state->bpf_fd) == -1)
+                       logerr(__func__);
+       }
+}
+
 static void
 arp_read(void *arg)
 {
@@ -214,10 +235,8 @@ arp_read(void *arg)
        }
        if (state != NULL) {
                state->bpf_flags &= ~BPF_READING;
-               if (state->bpf_flags & BPF_FREE) {
-                       free(state);
-                       ifp->if_data[IF_DATA_ARP] = NULL;
-               }
+               if (state->bpf_flags & BPF_FREE)
+                       arp_tryfree(ifp);
        }
 }
 
@@ -507,19 +526,7 @@ arp_free(struct arp_state *astate)
        if (astate->free_cb)
                astate->free_cb(astate);
        free(astate);
-
-       /* If there are no more ARP states, close the socket. */
-       if (TAILQ_FIRST(&state->arp_states) == NULL) {
-               arp_close(ifp);
-               if (state->bpf_flags & BPF_READING)
-                       state->bpf_flags |= BPF_EOF | BPF_FREE;
-               else {
-                       free(state);
-                       ifp->if_data[IF_DATA_ARP] = NULL;
-               }
-       } else
-               if (bpf_arp(ifp, state->bpf_fd) == -1)
-                       logerr(__func__);
+       arp_tryfree(ifp);
 }
 
 static void