]> git.ipfire.org Git - thirdparty/dhcpcd.git/commitdiff
IPv6: Avoid uninitialized ifp state when adding address (#395)
authorKen Simon <ken@kensimon.io>
Tue, 29 Oct 2024 23:11:54 +0000 (19:11 -0400)
committerGitHub <noreply@github.com>
Tue, 29 Oct 2024 23:11:54 +0000 (23:11 +0000)
In certain instances, `ifp->if_data[IF_DATA_IPV6]` was not yet
initialized when ipv6_addaddr adds the address to the state, and a
segfault would ensue. Mitigate this by ensuring the state is initialized
when adding the addresses.

fixes #394

src/ipv6.c

index c746f775a0ada9d71a2d2432140d2e19f6a59b03..a4221a8c0a1ca66a6f4b1b6a4d50362afbbab385 100644 (file)
@@ -654,6 +654,25 @@ ipv6_deleteaddr(struct ipv6_addr *ia)
        }
 }
 
+static struct ipv6_state *
+ipv6_getstate(struct interface *ifp)
+{
+       struct ipv6_state *state;
+
+       state = IPV6_STATE(ifp);
+       if (state == NULL) {
+               ifp->if_data[IF_DATA_IPV6] = calloc(1, sizeof(*state));
+               state = IPV6_STATE(ifp);
+               if (state == NULL) {
+                       logerr(__func__);
+                       return NULL;
+               }
+               TAILQ_INIT(&state->addrs);
+               TAILQ_INIT(&state->ll_callbacks);
+       }
+       return state;
+}
+
 static int
 ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
 {
@@ -785,7 +804,7 @@ ipv6_addaddr1(struct ipv6_addr *ia, const struct timespec *now)
         * it does not exist.
         * This is important if route overflow loses the message. */
        if (iaf == NULL) {
-               struct ipv6_state *state = IPV6_STATE(ifp);
+               struct ipv6_state *state = ipv6_getstate(ifp);
 
                if ((iaf = malloc(sizeof(*iaf))) == NULL) {
                        logerr(__func__);
@@ -1066,25 +1085,6 @@ ipv6_freedrop_addrs(struct ipv6_addrhead *addrs, int drop,
        }
 }
 
-static struct ipv6_state *
-ipv6_getstate(struct interface *ifp)
-{
-       struct ipv6_state *state;
-
-       state = IPV6_STATE(ifp);
-       if (state == NULL) {
-               ifp->if_data[IF_DATA_IPV6] = calloc(1, sizeof(*state));
-               state = IPV6_STATE(ifp);
-               if (state == NULL) {
-                       logerr(__func__);
-                       return NULL;
-               }
-               TAILQ_INIT(&state->addrs);
-               TAILQ_INIT(&state->ll_callbacks);
-       }
-       return state;
-}
-
 static struct ipv6_addr *
 ipv6_ifanyglobal(struct interface *ifp)
 {