Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src 4 new sysctls to avoid ipv6 DoS attacks from OpenBSD



details:   https://anonhg.NetBSD.org/src/rev/86e033eca8f4
branches:  trunk
changeset: 779858:86e033eca8f4
user:      christos <christos%NetBSD.org@localhost>
date:      Sat Jun 23 03:13:41 2012 +0000

description:
4 new sysctls to avoid ipv6 DoS attacks from OpenBSD

diffstat:

 share/man/man7/sysctl.7  |  24 +++++++++++++-
 sys/netinet6/icmp6.c     |   6 ++-
 sys/netinet6/in6.c       |   6 ++-
 sys/netinet6/in6_proto.c |   8 +++-
 sys/netinet6/in6_var.h   |   4 +-
 sys/netinet6/ip6_input.c |  36 ++++++++++++++++++++-
 sys/netinet6/ip6_var.h   |   7 +++-
 sys/netinet6/nd6.c       |  52 ++++++++++++++++++++++++++++++-
 sys/netinet6/nd6.h       |   5 ++-
 sys/netinet6/nd6_rtr.c   |  79 +++++++++++++++++++++++++++++++++++++++++++++--
 10 files changed, 208 insertions(+), 19 deletions(-)

diffs (truncated from 524 to 300 lines):

diff -r 96833b670c1b -r 86e033eca8f4 share/man/man7/sysctl.7
--- a/share/man/man7/sysctl.7   Fri Jun 22 22:54:26 2012 +0000
+++ b/share/man/man7/sysctl.7   Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-.\"    $NetBSD: sysctl.7,v 1.72 2012/06/22 14:54:35 christos Exp $
+.\"    $NetBSD: sysctl.7,v 1.73 2012/06/23 03:13:41 christos Exp $
 .\"
 .\" Copyright (c) 1993
 .\"    The Regents of the University of California.  All rights reserved.
@@ -29,7 +29,7 @@
 .\"
 .\"    @(#)sysctl.3    8.4 (Berkeley) 5/9/95
 .\"
-.Dd June 20, 2012
+.Dd June 22, 2012
 .Dt SYSCTL 7
 .Os
 .Sh NAME
@@ -1614,9 +1614,13 @@
 .It ip6        log_interval    integer yes
 .It ip6        lowportmax      integer yes
 .It ip6        lowportmin      integer yes
+.It ip6        maxdynroutes    integer yes
+.It ip6        maxifprefixes   integer yes
+.It ip6        maxifdefrouters integer yes
 .It ip6        maxflows        integer yes
 .It ip6        maxfragpackets  integer yes
 .It ip6        maxfrags        integer yes
+.It ip6        neighborgcthresh        integer yes
 .It ip6        redirect        integer yes
 .It ip6        rr_prune        integer yes
 .It ip6        use_deprecated  integer yes
@@ -1715,6 +1719,18 @@
 This cannot be set to less than 0 or greater than 1024, and must
 be smaller than
 .Li ip6.lowportmax .
+.It Li ip6.maxdynroutes
+Maximum number of routes created by redirect.
+Set it to negative to disable.
+The default value is 4096.
+.It Li ip6.maxifprefixes
+Maximum number of prefixes created by route advertisements per interface.
+Set it to negative to disable.
+The default value is 16.
+.It Li ip6.maxifdefrouters 16
+Maximum number of default routers created by route advertisements per interface.
+Set it to negative to disable.
+The default value is 16.
 .It Li ip6.maxflows
 IPv6 Fast Forwarding is enabled by default.
 If set to 0, IPv6 Fast Forwarding is disabled.
@@ -1731,6 +1747,10 @@
 0 means that the node will not accept any fragments.
 \-1 means that the node will accept as many fragments as it receives.
 The flag is provided basically for avoiding possible DoS attacks.
+.It Li ip6.neighborgcthresh
+Maximum number of entries in neighbor cache.
+Set to negative to disable.
+The default value is 2048.
 .It Li ip6.redirect
 If set to 1, ICMPv6 redirects may be sent by the node.
 This option is ignored unless the node is routing IP packets,
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/icmp6.c
--- a/sys/netinet6/icmp6.c      Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/icmp6.c      Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: icmp6.c,v 1.160 2012/03/22 20:34:40 drochner Exp $     */
+/*     $NetBSD: icmp6.c,v 1.161 2012/06/23 03:14:03 christos Exp $     */
 /*     $KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $ */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.160 2012/03/22 20:34:40 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.161 2012/06/23 03:14:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -2279,6 +2279,8 @@
                 * (there will be additional hops, though).
                 */
                rtcount = rt_timer_count(icmp6_redirect_timeout_q);
+               if (0 <= ip6_maxdynroutes && rtcount >= ip6_maxdynroutes)
+                       goto freeit;
                if (0 <= icmp6_redirect_hiwat && rtcount > icmp6_redirect_hiwat)
                        return;
                else if (0 <= icmp6_redirect_lowat &&
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/in6.c
--- a/sys/netinet6/in6.c        Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/in6.c        Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6.c,v 1.160 2012/03/13 18:40:59 elad Exp $   */
+/*     $NetBSD: in6.c,v 1.161 2012/06/23 03:14:03 christos Exp $       */
 /*     $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $   */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.160 2012/03/13 18:40:59 elad Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.161 2012/06/23 03:14:03 christos Exp $");
 
 #include "opt_inet.h"
 #include "opt_pfil_hooks.h"
@@ -2283,6 +2283,8 @@
 
        ext->nd_ifinfo = nd6_ifattach(ifp);
        ext->scope6_id = scope6_ifattach(ifp);
+       ext->nprefixes = 0;
+       ext->ndefrouters = 0;
        return ext;
 }
 
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/in6_proto.c
--- a/sys/netinet6/in6_proto.c  Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/in6_proto.c  Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_proto.c,v 1.96 2012/03/22 20:34:40 drochner Exp $  */
+/*     $NetBSD: in6_proto.c,v 1.97 2012/06/23 03:14:03 christos Exp $  */
 /*     $KAME: in6_proto.c,v 1.66 2000/10/10 15:35:47 itojun Exp $      */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.96 2012/03/22 20:34:40 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_proto.c,v 1.97 2012/06/23 03:14:03 christos Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -439,6 +439,10 @@
                                 * walk list every 5 sec. */
 int    ip6_mcast_pmtu = 0;     /* enable pMTU discovery for multicast? */
 int    ip6_v6only = 1;
+int     ip6_neighborgcthresh = 2048; /* Threshold # of NDP entries for GC */
+int     ip6_maxifprefixes = 16; /* Max acceptable prefixes via RA per IF */
+int     ip6_maxifdefrouters = 16; /* Max acceptable def routers via RA */
+int     ip6_maxdynroutes = 4096; /* Max # of routes created via redirect */
 
 int    ip6_keepfaith = 0;
 time_t ip6_log_time = 0;
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/in6_var.h
--- a/sys/netinet6/in6_var.h    Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/in6_var.h    Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: in6_var.h,v 1.64 2009/01/15 23:22:15 christos Exp $    */
+/*     $NetBSD: in6_var.h,v 1.65 2012/06/23 03:14:03 christos Exp $    */
 /*     $KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $        */
 
 /*
@@ -94,6 +94,8 @@
        struct icmp6_ifstat *icmp6_ifstat;
        struct nd_ifinfo *nd_ifinfo;
        struct scope6_id *scope6_id;
+       int nprefixes;
+       int ndefrouters;
 };
 
 struct in6_ifaddr {
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/ip6_input.c
--- a/sys/netinet6/ip6_input.c  Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/ip6_input.c  Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_input.c,v 1.138 2012/06/22 14:54:35 christos Exp $ */
+/*     $NetBSD: ip6_input.c,v 1.139 2012/06/23 03:14:04 christos Exp $ */
 /*     $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $     */
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.138 2012/06/22 14:54:35 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.139 2012/06/23 03:14:04 christos Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -1977,6 +1977,38 @@
                       SYSCTL_DESCR("selected algorithm"),
                       sysctl_rfc6056_selected6, 0, NULL, RFC6056_MAXLEN,
                       CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, NULL,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "neighborgcthresh",
+                      SYSCTL_DESCR("Maximum number of entries in neighbor"
+                       " cache"),
+                      NULL, 1, &ip6_neighborgcthresh, 0,
+                      CTL_NET, PF_INET6, IPPROTO_IPV6,
+                      CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, NULL,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "maxifprefixes",
+                      SYSCTL_DESCR("Maximum number of prefixes created by"
+                          " route advertisement per interface"),
+                      NULL, 1, &ip6_maxifprefixes, 0,
+                      CTL_NET, PF_INET6, IPPROTO_IPV6,
+                      CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, NULL,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "maxifdefrouters",
+                      SYSCTL_DESCR("Maximum number of default routers created"
+                          " by route advertisement per interface"),
+                      NULL, 1, &ip6_maxifdefrouters, 0,
+                      CTL_NET, PF_INET6, IPPROTO_IPV6,
+                      CTL_CREATE, CTL_EOL);
+       sysctl_createv(clog, 0, NULL, NULL,
+                      CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
+                      CTLTYPE_INT, "maxdynroutes",
+                      SYSCTL_DESCR("Maximum number of routes created via"
+                          " redirect"),
+                      NULL, 1, &ip6_maxdynroutes, 0,
+                      CTL_NET, PF_INET6, IPPROTO_IPV6,
+                      CTL_CREATE, CTL_EOL);
 }
 
 void
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/ip6_var.h
--- a/sys/netinet6/ip6_var.h    Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/ip6_var.h    Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: ip6_var.h,v 1.58 2012/01/19 13:19:34 liamjfoy Exp $    */
+/*     $NetBSD: ip6_var.h,v 1.59 2012/06/23 03:14:04 christos Exp $    */
 /*     $KAME: ip6_var.h,v 1.33 2000/06/11 14:59:20 jinmei Exp $        */
 
 /*
@@ -272,6 +272,11 @@
                                         * walk list every 5 sec.    */
 extern int     ip6_mcast_pmtu;         /* enable pMTU discovery for multicast? */
 extern int     ip6_v6only;
+extern int     ip6_neighborgcthresh;   /* Threshold # of NDP entries for GC */
+extern int     ip6_maxifprefixes; /* Max acceptable prefixes via RA per IF */
+extern int     ip6_maxifdefrouters;    /* Max acceptable def routers via RA */
+extern int     ip6_maxdynroutes; /* Max # of routes created via redirect */
+
 
 extern struct socket *ip6_mrouter;     /* multicast routing daemon */
 extern int     ip6_sendredirects;      /* send IP redirects when forwarding? */
diff -r 96833b670c1b -r 86e033eca8f4 sys/netinet6/nd6.c
--- a/sys/netinet6/nd6.c        Fri Jun 22 22:54:26 2012 +0000
+++ b/sys/netinet6/nd6.c        Sat Jun 23 03:13:41 2012 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: nd6.c,v 1.142 2012/03/22 20:34:41 drochner Exp $       */
+/*     $NetBSD: nd6.c,v 1.143 2012/06/23 03:14:04 christos Exp $       */
 /*     $KAME: nd6.c,v 1.279 2002/06/08 11:16:51 itojun Exp $   */
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.142 2012/03/22 20:34:41 drochner Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6.c,v 1.143 2012/06/23 03:14:04 christos Exp $");
 
 #include "opt_ipsec.h"
 
@@ -131,6 +131,16 @@
 
 MALLOC_DEFINE(M_IP6NDP, "NDP", "IPv6 Neighbour Discovery");
 
+#define LN_DEQUEUE(ln) do { \
+       (ln)->ln_next->ln_prev = (ln)->ln_prev; \
+       (ln)->ln_prev->ln_next = (ln)->ln_next; \
+       } while (/*CONSTCOND*/0)
+#define LN_INSERTHEAD(ln) do { \
+       (ln)->ln_next = llinfo_nd6.ln_next; \
+       llinfo_nd6.ln_next = (ln); \
+       (ln)->ln_prev = &llinfo_nd6; \
+       (ln)->ln_next->ln_prev = (ln); \
+       } while (/*CONSTCOND*/0)
 void
 nd6_init(void)
 {
@@ -473,6 +483,7 @@
                }
                break;
 
+       case ND6_LLINFO_PURGE:
        case ND6_LLINFO_STALE:
                /* Garbage Collection(RFC 2461 5.3) */
                if (!ND6_LLINFO_PERMANENT(ln)) {
@@ -1332,6 +1343,35 @@
                ln->ln_prev = &llinfo_nd6;
                ln->ln_next->ln_prev = ln;
 
+               /*
+                * If we have too many cache entries, initiate immediate
+                * purging for some "less recently used" entries.  Note that
+                * we cannot directly call nd6_free() here because it would
+                * cause re-entering rtable related routines triggering an LOR
+                * problem for FreeBSD.
+                */
+               if (ip6_neighborgcthresh >= 0 &&
+                   nd6_inuse >= ip6_neighborgcthresh) {
+                       int i;
+
+                       for (i = 0; i < 10 && llinfo_nd6.ln_prev != ln; i++) {



Home | Main Index | Thread Index | Old Index