Index: ip6_input.c =================================================================== RCS file: /cvsroot/kame/kame/kame/sys/netinet6/ip6_input.c,v retrieving revision 1.370 retrieving revision 1.373 diff -u -r1.370 -r1.373 --- ip6_input.c 8 Apr 2007 17:04:31 -0000 1.370 +++ ip6_input.c 8 May 2007 02:53:12 -0000 1.373 @@ -375,7 +375,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; #if 0 struct mbuf *mhist; /* onion peeling history */ @@ -1056,9 +1056,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; } @@ -1088,6 +1090,30 @@ } #endif + /* + * 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; + } + } + #if defined(IPSEC) && !defined(__OpenBSD__) /* * enforce IPsec policy checking if we are seeing last header. Index: route6.c =================================================================== RCS file: /cvsroot/kame/kame/kame/sys/netinet6/route6.c,v retrieving revision 1.60 retrieving revision 1.64 diff -u -r1.60 -r1.64 --- route6.c 25 Jun 2006 02:21:47 -0000 1.60 +++ route6.c 5 May 2007 11:23:38 -0000 1.64 @@ -62,8 +62,10 @@ #include +#if 0 static int ip6_rthdr0 __P((struct mbuf *, struct ip6_hdr *, struct ip6_rthdr0 *)); +#endif #if defined(MIP6) && NMIP > 0 static int ip6_rthdr2 __P((struct mbuf *, struct ip6_hdr *, @@ -106,6 +108,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: rhlen = (rh->ip6r_len + 1) << 3; if (rh->ip6r_segleft == 0) @@ -135,6 +153,7 @@ if (ip6_rthdr0(m, ip6, (struct ip6_rthdr0 *)rh)) return (IPPROTO_DONE); break; +#endif #if defined(MIP6) && NMIP > 0 case IPV6_RTHDR_TYPE_2: rhlen = (rh->ip6r_len + 1) << 3; @@ -170,6 +189,7 @@ return (rh->ip6r_nxt); } +#if 0 /* * Type0 routing header processing * @@ -260,6 +280,7 @@ m_freem(m); return (-1); } +#endif #if defined(MIP6) && NMIP > 0 /* Type2 routing header processing */ Index: in6_proto.c =================================================================== RCS file: /cvsroot/kame/kame/kame/sys/netinet6/in6_proto.c,v retrieving revision 1.163 retrieving revision 1.164 diff -u -r1.163 -r1.164 --- in6_proto.c 3 Nov 2005 10:26:03 -0000 1.163 +++ in6_proto.c 8 May 2007 12:05:12 -0000 1.164 @@ -595,7 +595,7 @@ int ip6_maxfrags = 200; #endif 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_use_deprecated = 1; /* allow deprecated addr (RFC2462 5.5.4) */