Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F151527300
D22712.id69173.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
3 KB
Referenced Files
None
Subscribers
None
D22712.id69173.diff
View Options
Index: sys/netinet6/nd6_rtr.c
===================================================================
--- sys/netinet6/nd6_rtr.c
+++ sys/netinet6/nd6_rtr.c
@@ -68,6 +68,7 @@
#include <netinet6/in6_var.h>
#include <netinet6/in6_ifattach.h>
#include <netinet/ip6.h>
+#include <netinet/icmp6.h>
#include <netinet6/ip6_var.h>
#include <netinet6/nd6.h>
#include <netinet/icmp6.h>
@@ -103,6 +104,28 @@
SYSCTL_DECL(_net_inet6_icmp6);
+/*
+ * Global limit and per-VNET count for the maximum amount of default routers
+ * we accept in the list and equally for prefixes.
+ * The sysctls are not adjustable per-VNET to keep things simple and avoid
+ * VNETs allowing themselves to be a DoS target exhausting memory. Otherwise
+ * we need to make this a PROC as well and handle a global max cap per-vnet.
+ */
+static int nd6_defrouter_max = 16;
+SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_defrouter_max,
+ CTLFLAG_RW, &nd6_defrouter_max, 0,
+ "Maximum number of IPv6 default routers. 0 accept unlimited.");
+VNET_DEFINE_STATIC(int, nd6_defrouter_cur);
+#define V_nd6_defrouter_cur VNET(nd6_defrouter_cur)
+
+static int nd6_prefixes_max = 64;
+SYSCTL_INT(_net_inet6_icmp6, OID_AUTO, nd6_prefixes_max,
+ CTLFLAG_RW, &nd6_prefixes_max, 0,
+ "Maximum number of IPv6 prefix list entries. 0 accept unlimited.");
+VNET_DEFINE_STATIC(int, nd6_prefixes_cur);
+#define V_nd6_prefixes_cur VNET(nd6_prefixes_cur)
+
+
/* RTPREF_MEDIUM has to be 0! */
#define RTPREF_HIGH 1
#define RTPREF_MEDIUM 0
@@ -136,6 +159,7 @@
ND6_WLOCK_ASSERT();
TAILQ_REMOVE(&V_nd6_defrouter, dr, dr_entry);
+ V_nd6_defrouter_cur--;
V_nd6_list_genid++;
if (drq != NULL)
TAILQ_INSERT_TAIL(drq, dr, dr_entry);
@@ -1102,10 +1126,20 @@
/*
* The preferred router may have changed, so relocate this
* router.
+ * We are removing the dr from the list only to re-add it
+ * later, so we skip any default router list limit checks here.
+ * This way we make sure we do not lose a (hopefully) valid
+ * and working default router in case we are under attack.
*/
TAILQ_REMOVE(&V_nd6_defrouter, dr, dr_entry);
n = dr;
} else {
+ if (nd6_defrouter_max > 0 &&
+ V_nd6_defrouter_cur >= nd6_defrouter_max) {
+ ND6_WUNLOCK();
+ ICMP6STAT_INC(icp6s_overflowdefrtr);
+ return (NULL);
+ }
n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
if (n == NULL) {
ND6_WUNLOCK();
@@ -1114,6 +1148,7 @@
memcpy(n, new, sizeof(*n));
/* Initialize with an extra reference for the caller. */
refcount_init(&n->refcnt, 2);
+ V_nd6_defrouter_cur++;
}
/*
@@ -1369,7 +1404,14 @@
IN6_MASK_ADDR(&new->ndpr_prefix.sin6_addr, &new->ndpr_mask);
ND6_WLOCK();
+ if (nd6_prefixes_max > 0 && V_nd6_prefixes_cur >= nd6_prefixes_max) {
+ ND6_WUNLOCK();
+ ICMP6STAT_INC(icp6s_overflowprfx);
+ free(new, M_IP6NDP);
+ return (ENOBUFS);
+ }
LIST_INSERT_HEAD(&V_nd_prefix, new, ndpr_entry);
+ V_nd6_prefixes_cur++;
V_nd6_list_genid++;
ND6_WUNLOCK();
@@ -1410,6 +1452,7 @@
ND6_WLOCK_ASSERT();
LIST_REMOVE(pr, ndpr_entry);
+ V_nd6_prefixes_cur--;
V_nd6_list_genid++;
if (list != NULL)
LIST_INSERT_HEAD(list, pr, ndpr_entry);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Apr 10, 12:58 AM (12 h, 55 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
31183889
Default Alt Text
D22712.id69173.diff (3 KB)
Attached To
Mode
D22712: Add Router and Prefix table limits.
Attached
Detach File
Event Timeline
Log In to Comment