Commit d1818806 authored by Alexey Kuznetsov's avatar Alexey Kuznetsov Committed by David S. Miller

IPV6 addrconf exploit fix:

- stop external DoS attack feeding lots of IPv6 prefixes
parent 1009695b
...@@ -62,6 +62,8 @@ ...@@ -62,6 +62,8 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#define IPV6_MAX_ADDRESSES 16
/* Set to 3 to get tracing... */ /* Set to 3 to get tracing... */
#define ACONF_DEBUG 2 #define ACONF_DEBUG 2
...@@ -586,6 +588,18 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) ...@@ -586,6 +588,18 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr)
return err; return err;
} }
int ipv6_count_addresses(struct inet6_dev *idev)
{
int cnt = 0;
struct inet6_ifaddr *ifp;
read_lock_bh(&idev->lock);
for (ifp=idev->addr_list; ifp; ifp=ifp->if_next)
cnt++;
read_unlock_bh(&idev->lock);
return cnt;
}
int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev) int ipv6_chk_addr(struct in6_addr *addr, struct net_device *dev)
{ {
struct inet6_ifaddr * ifp; struct inet6_ifaddr * ifp;
...@@ -895,8 +909,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len) ...@@ -895,8 +909,12 @@ void addrconf_prefix_rcv(struct net_device *dev, u8 *opt, int len)
ifp = ipv6_get_ifaddr(&addr, dev); ifp = ipv6_get_ifaddr(&addr, dev);
if (ifp == NULL && valid_lft) { if (ifp == NULL && valid_lft) {
ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len, /* Do not allow to create too much of autoconfigured
addr_type&IPV6_ADDR_SCOPE_MASK, 0); * addresses; this would be too easy way to crash kernel.
*/
if (ipv6_count_addresses(in6_dev) < IPV6_MAX_ADDRESSES)
ifp = ipv6_add_addr(in6_dev, &addr, pinfo->prefix_len,
addr_type&IPV6_ADDR_SCOPE_MASK, 0);
if (ifp == NULL) { if (ifp == NULL) {
in6_dev_put(in6_dev); in6_dev_put(in6_dev);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment