Message ID | 1378908069-18235-1-git-send-email-luis.henriques@canonical.com |
---|---|
State | New |
Headers | show |
On 09/11/2013 09:01 AM, Luis Henriques wrote: > From: Hannes Frederic Sowa <hannes@stressinduktion.org> > > BugLink: http://bugs.launchpad.net/bugs/1143800 > > CVE-2013-0343 > > Because of the max_addresses check attackers were able to disable privacy > extensions on an interface by creating enough autoconfigured addresses: > > <http://seclists.org/oss-sec/2012/q4/292> > > But the check is not actually needed: max_addresses protects the > kernel to install too many ipv6 addresses on an interface and guards > addrconf_prefix_rcv to install further addresses as soon as this limit > is reached. We only generate temporary addresses in direct response of > a new address showing up. As soon as we filled up the maximum number of > addresses of an interface, we stop installing more addresses and thus > also stop generating more temp addresses. > > Even if the attacker tries to generate a lot of temporary addresses > by announcing a prefix and removing it again (lifetime == 0) we won't > install more temp addresses, because the temporary addresses do count > to the maximum number of addresses, thus we would stop installing new > autoconfigured addresses when the limit is reached. > > This patch fixes CVE-2013-0343 (but other layer-2 attacks are still > possible). > > Thanks to Ding Tianhong to bring this topic up again. > > Cc: Ding Tianhong <dingtianhong@huawei.com> > Cc: George Kargiotakis <kargig@void.gr> > Cc: P J P <ppandit@redhat.com> > Cc: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> > Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org> > Acked-by: Ding Tianhong <dingtianhong@huawei.com> > Signed-off-by: David S. Miller <davem@davemloft.net> > (back ported from commit 4b08a8f1bd8cb4541c93ec170027b4d0782dab52) > Signed-off-by: Luis Henriques <luis.henriques@canonical.com> > --- > net/ipv6/addrconf.c | 10 ++++------ > 1 file changed, 4 insertions(+), 6 deletions(-) > > diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c > index e23be1f..c0a47ec 100644 > --- a/net/ipv6/addrconf.c > +++ b/net/ipv6/addrconf.c > @@ -920,12 +920,10 @@ retry: > if (ifp->flags & IFA_F_OPTIMISTIC) > addr_flags |= IFA_F_OPTIMISTIC; > > - ift = !max_addresses || > - ipv6_count_addresses(idev) < max_addresses ? > - ipv6_add_addr(idev, &addr, tmp_plen, > - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > - addr_flags) : NULL; > - if (!ift || IS_ERR(ift)) { > + ift = ipv6_add_addr(idev, &addr, tmp_plen, > + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, > + addr_flags); > + if (IS_ERR(ift)) { > in6_ifa_put(ifp); > in6_dev_put(idev); > printk(KERN_INFO >
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index e23be1f..c0a47ec 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -920,12 +920,10 @@ retry: if (ifp->flags & IFA_F_OPTIMISTIC) addr_flags |= IFA_F_OPTIMISTIC; - ift = !max_addresses || - ipv6_count_addresses(idev) < max_addresses ? - ipv6_add_addr(idev, &addr, tmp_plen, - ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, - addr_flags) : NULL; - if (!ift || IS_ERR(ift)) { + ift = ipv6_add_addr(idev, &addr, tmp_plen, + ipv6_addr_type(&addr)&IPV6_ADDR_SCOPE_MASK, + addr_flags); + if (IS_ERR(ift)) { in6_ifa_put(ifp); in6_dev_put(idev); printk(KERN_INFO