数年ぶりの投稿の野沢と申します。

FreeBSD-SA-07:03.ipv6 の patch だけでは十分ではないと itojun さんから聞き、
私が使用している 6.2-RELEASE-p4 で patch を作りました。
#たまには貢献できればと思いまして (^^)

元は
http://www.kame.net/newsletter/20070502/index.ja.html
です。

current では、どうなっているかご存知な方いらっしゃいますか?

#んー、今になって route6.c の "@@ -89,6 +91,22 @@" の部分が気になってきた (^^;
--- sys/netinet6/in6_proto.c.orig	Fri May  4 15:14:10 2007
+++ sys/netinet6/in6_proto.c	Fri May 18 13:52:14 2007
@@ -361,7 +361,7 @@
 int	ip6_maxfragpackets;	/* initialized in frag6.c:frag6_init() */
 int	ip6_maxfrags;	/* initialized in frag6.c:frag6_init() */
 int	ip6_log_interval = 5;
-int	ip6_hdrnestlimit = 50;	/* appropriate? */
+int	ip6_hdrnestlimit = 15;	/* appropriate? */
 int	ip6_dad_count = 1;	/* DupAddrDetectionTransmits */
 int	ip6_auto_flowlabel = 1;
 int	ip6_gif_hlim = 0;
--- sys/netinet6/ip6_input.c.orig	Wed Feb  1 01:36:11 2006
+++ sys/netinet6/ip6_input.c	Mon May 21 10:30:14 2007
@@ -234,7 +234,7 @@
 	int off = sizeof(struct ip6_hdr), nest;
 	u_int32_t plen;
 	u_int32_t rtalert = ~0;
-	int nxt, ours = 0;
+	int nxt, ours = 0, rh_present = 0;
 	struct ifnet *deliverifp = NULL;
 	struct in6_addr odst;
 	int srcrt = 0;
@@ -758,9 +758,11 @@
 	in6_ifstat_inc(deliverifp, ifs6_in_deliver);
 	nest = 0;
 
+	rh_present = 0;
 	while (nxt != IPPROTO_DONE) {
 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
 			ip6stat.ip6s_toomanyhdr++;
+			in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr);
 			goto bad;
 		}
 
@@ -774,6 +776,30 @@
 			goto bad;
 		}
 
+ 		/*
+ 		 * Here we try to reject packets with more than 1 routing
+ 		 * headers.  we do this here (instead of tagging mbuf route6.c) 
+ 		 * for the sake of computational costs, such as malloc().
+ 		 *
+ 		 * The code could be too restrictive - there could be
+ 		 * actual use of more than 1 routing headers on a packet
+ 		 * which cannot be used to do bad things unlike
+ 		 * IPV6_RTHDR_TYPE_0.  This code could also prohibit a mixed use
+ 		 * of TYPE_x and TYPE_y routing headers (x != y) even if it is
+ 		 * safe.
+ 		 *
+ 		 * We may need to revisit this behavior if and when a new type
+ 		 * of routing header is defined.
+ 		 */
+ 		if (nxt == IPPROTO_ROUTING) {
+ 			if (rh_present++) {
+ 				in6_ifstat_inc(m->m_pkthdr.rcvif,
+ 				    ifs6_in_hdrerr);
+ 				ip6stat.ip6s_badoptions++;
+ 				goto bad;
+ 			}
+ 		}
+ 
 #ifdef IPSEC
 		/*
 		 * enforce IPsec policy checking if we are seeing last header.
--- sys/netinet6/route6.c.orig	Fri May  4 15:14:10 2007
+++ sys/netinet6/route6.c	Mon May 21 10:40:12 2007
@@ -51,8 +51,10 @@
 
 extern int ip6_rthdr0_allowed;
 
+#if 0
 static int ip6_rthdr0 __P((struct mbuf *, struct ip6_hdr *,
     struct ip6_rthdr0 *));
+#endif
 
 int
 route6_input(mp, offp, proto)
@@ -89,6 +91,22 @@
 #endif
 
 	switch (rh->ip6r_type) {
+#if 0
+	/*
+	 * See http://www.secdev.org/conf/IPv6_RH_security-csw07.pdf
+	 * for why IPV6_RTHDR_TYPE_0 is banned here.
+	 *
+	 * We return ICMPv6 parameter problem so that innocent people
+	 * (not an attacker) would notice about the use of IPV6_RTHDR_TYPE_0.
+	 * Since there's no amplification, and ICMPv6 error will be rate-
+	 * controlled, it shouldn't cause any problem.
+	 * If you are concerned about this, you may want to use the following
+	 * code fragment:
+	 *
+	 * case IPV6_RTHDR_TYPE_0:
+	 *	m_freem(m);
+	 *	return (IPPROTO_DONE);
+	 */
 	case IPV6_RTHDR_TYPE_0:
 		if (!ip6_rthdr0_allowed)
 			return (IPPROTO_DONE);
@@ -118,6 +136,7 @@
 		if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh))
 			return (IPPROTO_DONE);
 		break;
+#endif
 	default:
 		/* unknown routing type */
 		if (rh->ip6r_segleft == 0) {
@@ -134,6 +153,7 @@
 	return (rh->ip6r_nxt);
 }
 
+#if 0
 /*
  * Type0 routing header processing
  *
@@ -237,3 +257,4 @@
 	m_freem(m);
 	return (-1);
 }
+#endif

メールによる返信