aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6
diff options
context:
space:
mode:
authorYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>2007-04-24 17:58:30 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-24 17:58:30 -0400
commit0bcbc92629044b5403719f77fb015e9005b1f504 (patch)
treeac9635a8ac7b14edcaa0e5ad42a5bc70f778ec33 /net/ipv6
parent05d224468a273a9ee773a0e9d34227ee7f2c0840 (diff)
[IPV6]: Disallow RH0 by default.
A security issue is emerging. Disallow Routing Header Type 0 by default as we have been doing for IPv4. Note: We allow RH2 by default because it is harmless. Signed-off-by: YOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6')
-rw-r--r--net/ipv6/addrconf.c11
-rw-r--r--net/ipv6/exthdrs.c40
2 files changed, 45 insertions, 6 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 7552663aa125..452a82ce4796 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -172,6 +172,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = {
172#endif 172#endif
173#endif 173#endif
174 .proxy_ndp = 0, 174 .proxy_ndp = 0,
175 .accept_source_route = 0, /* we do not accept RH0 by default. */
175}; 176};
176 177
177static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = { 178static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
@@ -203,6 +204,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
203#endif 204#endif
204#endif 205#endif
205 .proxy_ndp = 0, 206 .proxy_ndp = 0,
207 .accept_source_route = 0, /* we do not accept RH0 by default. */
206}; 208};
207 209
208/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */ 210/* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
@@ -3356,6 +3358,7 @@ static inline void ipv6_store_devconf(struct ipv6_devconf *cnf,
3356#endif 3358#endif
3357#endif 3359#endif
3358 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp; 3360 array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
3361 array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
3359} 3362}
3360 3363
3361static inline size_t inet6_if_nlmsg_size(void) 3364static inline size_t inet6_if_nlmsg_size(void)
@@ -3884,6 +3887,14 @@ static struct addrconf_sysctl_table
3884 .proc_handler = &proc_dointvec, 3887 .proc_handler = &proc_dointvec,
3885 }, 3888 },
3886 { 3889 {
3890 .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
3891 .procname = "accept_source_route",
3892 .data = &ipv6_devconf.accept_source_route,
3893 .maxlen = sizeof(int),
3894 .mode = 0644,
3895 .proc_handler = &proc_dointvec,
3896 },
3897 {
3887 .ctl_name = 0, /* sentinel */ 3898 .ctl_name = 0, /* sentinel */
3888 } 3899 }
3889 }, 3900 },
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 28e0c6568272..6ed6a8cd6a68 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -362,10 +362,27 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
362 struct inet6_skb_parm *opt = IP6CB(skb); 362 struct inet6_skb_parm *opt = IP6CB(skb);
363 struct in6_addr *addr = NULL; 363 struct in6_addr *addr = NULL;
364 struct in6_addr daddr; 364 struct in6_addr daddr;
365 struct inet6_dev *idev;
365 int n, i; 366 int n, i;
366
367 struct ipv6_rt_hdr *hdr; 367 struct ipv6_rt_hdr *hdr;
368 struct rt0_hdr *rthdr; 368 struct rt0_hdr *rthdr;
369 int accept_source_route = ipv6_devconf.accept_source_route;
370
371 if (accept_source_route < 0 ||
372 ((idev = in6_dev_get(skb->dev)) == NULL)) {
373 kfree_skb(skb);
374 return -1;
375 }
376 if (idev->cnf.accept_source_route < 0) {
377 in6_dev_put(idev);
378 kfree_skb(skb);
379 return -1;
380 }
381
382 if (accept_source_route > idev->cnf.accept_source_route)
383 accept_source_route = idev->cnf.accept_source_route;
384
385 in6_dev_put(idev);
369 386
370 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) || 387 if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
371 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) { 388 !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
@@ -377,6 +394,22 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
377 394
378 hdr = (struct ipv6_rt_hdr *) skb->h.raw; 395 hdr = (struct ipv6_rt_hdr *) skb->h.raw;
379 396
397 switch (hdr->type) {
398#ifdef CONFIG_IPV6_MIP6
399 break;
400#endif
401 case IPV6_SRCRT_TYPE_0:
402 if (accept_source_route <= 0)
403 break;
404 kfree_skb(skb);
405 return -1;
406 default:
407 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
408 IPSTATS_MIB_INHDRERRORS);
409 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
410 return -1;
411 }
412
380 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) || 413 if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
381 skb->pkt_type != PACKET_HOST) { 414 skb->pkt_type != PACKET_HOST) {
382 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst), 415 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
@@ -434,11 +467,6 @@ looped_back:
434 } 467 }
435 break; 468 break;
436#endif 469#endif
437 default:
438 IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
439 IPSTATS_MIB_INHDRERRORS);
440 icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
441 return -1;
442 } 470 }
443 471
444 /* 472 /*