summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorcperciva <cperciva@FreeBSD.org>2008-10-02 00:32:59 +0000
committercperciva <cperciva@FreeBSD.org>2008-10-02 00:32:59 +0000
commit678568e481a3fae7c641bf7fa9e8a100f417c803 (patch)
tree1fd570d319aaf51979955781b18f87d3fa93eeee /sys/netinet6
parent41bed7d06342a059bf166d2923dd9051694e36b3 (diff)
downloadFreeBSD-src-678568e481a3fae7c641bf7fa9e8a100f417c803.zip
FreeBSD-src-678568e481a3fae7c641bf7fa9e8a100f417c803.tar.gz
Default to ignoring potentially evil IPv6 Neighbor Solicitation
messages. Approved by: so (cperciva) Approved by: re (kensmith) Security: FreeBSD-SA-08:10.nd6 Thanks to: jinmei, bz
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/in6.h4
-rw-r--r--sys/netinet6/in6_proto.c4
-rw-r--r--sys/netinet6/nd6.h1
-rw-r--r--sys/netinet6/nd6_nbr.c18
4 files changed, 26 insertions, 1 deletions
diff --git a/sys/netinet6/in6.h b/sys/netinet6/in6.h
index db0ab11..ffdb37f4 100644
--- a/sys/netinet6/in6.h
+++ b/sys/netinet6/in6.h
@@ -599,7 +599,9 @@ struct ip6_mtuinfo {
/* New entries should be added here from current IPV6CTL_MAXID value. */
/* to define items, should talk with KAME guys first, for *BSD compatibility */
#define IPV6CTL_STEALTH 45
-#define IPV6CTL_MAXID 46
+
+#define ICMPV6CTL_ND6_ONLINKNSRFC4861 47
+#define IPV6CTL_MAXID 48
#endif /* __BSD_VISIBLE */
/*
diff --git a/sys/netinet6/in6_proto.c b/sys/netinet6/in6_proto.c
index c35a1b6..c1caaa5 100644
--- a/sys/netinet6/in6_proto.c
+++ b/sys/netinet6/in6_proto.c
@@ -403,6 +403,7 @@ time_t ip6_log_time = (time_t)0L;
#ifdef IPSTEALTH
int ip6stealth = 0;
#endif
+int nd6_onlink_ns_rfc4861 = 0; /* allow 'on-link' nd6 NS (as in RFC 4861) */
/* icmp6 */
/*
@@ -576,3 +577,6 @@ SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_MAXNUDHINT,
nd6_maxnudhint, CTLFLAG_RW, &nd6_maxnudhint, 0, "");
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_DEBUG,
nd6_debug, CTLFLAG_RW, &nd6_debug, 0, "");
+SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_ONLINKNSRFC4861,
+ nd6_onlink_ns_rfc4861, CTLFLAG_RW, &nd6_onlink_ns_rfc4861, 0,
+ "Accept 'on-link' nd6 NS in compliance with RFC 4861.");
diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h
index f191d2d..4b4d6ec 100644
--- a/sys/netinet6/nd6.h
+++ b/sys/netinet6/nd6.h
@@ -339,6 +339,7 @@ extern struct llinfo_nd6 llinfo_nd6;
extern struct nd_drhead nd_defrouter;
extern struct nd_prhead nd_prefix;
extern int nd6_debug;
+extern int nd6_onlink_ns_rfc4861;
#define nd6log(x) do { if (V_nd6_debug) log x; } while (/*CONSTCOND*/ 0)
diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c
index 3db6eca..770a40a 100644
--- a/sys/netinet6/nd6_nbr.c
+++ b/sys/netinet6/nd6_nbr.c
@@ -150,6 +150,24 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len)
"(wrong ip6 dst)\n"));
goto bad;
}
+ } else if (!nd6_onlink_ns_rfc4861) {
+ struct sockaddr_in6 src_sa6;
+
+ /*
+ * According to recent IETF discussions, it is not a good idea
+ * to accept a NS from an address which would not be deemed
+ * to be a neighbor otherwise. This point is expected to be
+ * clarified in future revisions of the specification.
+ */
+ bzero(&src_sa6, sizeof(src_sa6));
+ src_sa6.sin6_family = AF_INET6;
+ src_sa6.sin6_len = sizeof(src_sa6);
+ src_sa6.sin6_addr = saddr6;
+ if (!nd6_is_addr_neighbor(&src_sa6, ifp)) {
+ nd6log((LOG_INFO, "nd6_ns_input: "
+ "NS packet from non-neighbor\n"));
+ goto bad;
+ }
}
if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
OpenPOWER on IntegriCloud