]> www.infradead.org Git - users/dwmw2/linux.git/commitdiff
ipv4: Don't allocate ifa for 0.0.0.0 in inet_rtm_newaddr().
authorKuniyuki Iwashima <kuniyu@amazon.com>
Mon, 21 Oct 2024 18:32:31 +0000 (11:32 -0700)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 29 Oct 2024 10:54:57 +0000 (11:54 +0100)
When we pass 0.0.0.0 to __inet_insert_ifa(), it frees ifa and returns 0.

We can do this check much earlier for RTM_NEWADDR even before allocating
struct in_ifaddr.

Let's move the validation to

  1. inet_insert_ifa() for ioctl()
  2. inet_rtm_newaddr() for RTM_NEWADDR

Now, we can remove the same check in find_matching_ifa().

Signed-off-by: Kuniyuki Iwashima <kuniyu@amazon.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
net/ipv4/devinet.c

index da5412fb34e71f5ef8049bff9d5f13721da6352f..8db84c70ebedb07e21fa2b071b182a047f9df448 100644 (file)
@@ -508,11 +508,6 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
 
        ASSERT_RTNL();
 
-       if (!ifa->ifa_local) {
-               inet_free_ifa(ifa);
-               return 0;
-       }
-
        ifa->ifa_flags &= ~IFA_F_SECONDARY;
        last_primary = &in_dev->ifa_list;
 
@@ -584,6 +579,11 @@ static int __inet_insert_ifa(struct in_ifaddr *ifa, struct nlmsghdr *nlh,
 
 static int inet_insert_ifa(struct in_ifaddr *ifa)
 {
+       if (!ifa->ifa_local) {
+               inet_free_ifa(ifa);
+               return 0;
+       }
+
        return __inet_insert_ifa(ifa, NULL, 0, NULL);
 }
 
@@ -953,15 +953,13 @@ static struct in_ifaddr *find_matching_ifa(struct in_ifaddr *ifa)
        struct in_device *in_dev = ifa->ifa_dev;
        struct in_ifaddr *ifa1;
 
-       if (!ifa->ifa_local)
-               return NULL;
-
        in_dev_for_each_ifa_rtnl(ifa1, in_dev) {
                if (ifa1->ifa_mask == ifa->ifa_mask &&
                    inet_ifa_match(ifa1->ifa_address, ifa) &&
                    ifa1->ifa_local == ifa->ifa_local)
                        return ifa1;
        }
+
        return NULL;
 }
 
@@ -982,6 +980,9 @@ static int inet_rtm_newaddr(struct sk_buff *skb, struct nlmsghdr *nlh,
        if (ret < 0)
                return ret;
 
+       if (!nla_get_in_addr(tb[IFA_LOCAL]))
+               return 0;
+
        ifa = inet_rtm_to_ifa(net, nlh, tb, extack);
        if (IS_ERR(ifa))
                return PTR_ERR(ifa);