[FEISTY]: [PATCH] ipv6 security bug fix from stable kernel 2.6.20.9
Ben Collins
ben.collins at ubuntu.com
Thu May 3 14:55:57 UTC 2007
On Thu, 2007-05-03 at 13:58 +0100, Phillip Lougher wrote:
> >From 0f05828ef57fa9c1ed6e10d23a76ccaecc887583 Mon Sep 17 00:00:00 2001
> From: YOSHIFUJI Hideaki <yoshfuji at linux-ipv6.org>
> Date: Wed, 25 Apr 2007 21:56:57 -0700
> Subject: [PATCH] (ipv6 security bug fix from stable kernel 2.6.20.9)
>
> [PATCH] IPV6: Disallow RH0 by default.
>
> [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.
ACK, but note, this will change our ABI :/
> index f824113..713eb5e 100644
> --- a/include/linux/ipv6.h
> +++ b/include/linux/ipv6.h
> @@ -177,6 +177,7 @@ struct ipv6_devconf {
> #endif
> #endif
> __s32 proxy_ndp;
> + __s32 accept_source_route;
> void *sysctl;
> };
>
> @@ -205,6 +206,8 @@ enum {
> DEVCONF_RTR_PROBE_INTERVAL,
> DEVCONF_ACCEPT_RA_RT_INFO_MAX_PLEN,
> DEVCONF_PROXY_NDP,
> + __DEVCONF_OPTIMISTIC_DAD,
> + DEVCONF_ACCEPT_SOURCE_ROUTE,
> DEVCONF_MAX
> };
>
> diff --git a/include/linux/sysctl.h b/include/linux/sysctl.h
> index 81480e6..6f34622 100644
> --- a/include/linux/sysctl.h
> +++ b/include/linux/sysctl.h
> @@ -570,6 +570,7 @@ enum {
> NET_IPV6_RTR_PROBE_INTERVAL=21,
> NET_IPV6_ACCEPT_RA_RT_INFO_MAX_PLEN=22,
> NET_IPV6_PROXY_NDP=23,
> + NET_IPV6_ACCEPT_SOURCE_ROUTE=25,
> __NET_IPV6_MAX
> };
>
> diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
> index 58cb669..f5af4ca 100644
> --- a/net/ipv6/addrconf.c
> +++ b/net/ipv6/addrconf.c
> @@ -173,6 +173,7 @@ struct ipv6_devconf ipv6_devconf __read_mostly = {
> #endif
> #endif
> .proxy_ndp = 0,
> + .accept_source_route = 0, /* we do not accept RH0 by default. */
> };
>
> static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
> @@ -204,6 +205,7 @@ static struct ipv6_devconf ipv6_devconf_dflt __read_mostly = {
> #endif
> #endif
> .proxy_ndp = 0,
> + .accept_source_route = 0, /* we do not accept RH0 by default. */
> };
>
> /* IPv6 Wildcard Address and Loopback Address defined by RFC2553 */
> @@ -3400,6 +3402,7 @@ static void inline ipv6_store_devconf(struct ipv6_devconf *cnf,
> #endif
> #endif
> array[DEVCONF_PROXY_NDP] = cnf->proxy_ndp;
> + array[DEVCONF_ACCEPT_SOURCE_ROUTE] = cnf->accept_source_route;
> }
>
> static inline size_t inet6_if_nlmsg_size(void)
> @@ -3920,6 +3923,14 @@ static struct addrconf_sysctl_table
> .proc_handler = &proc_dointvec,
> },
> {
> + .ctl_name = NET_IPV6_ACCEPT_SOURCE_ROUTE,
> + .procname = "accept_source_route",
> + .data = &ipv6_devconf.accept_source_route,
> + .maxlen = sizeof(int),
> + .mode = 0644,
> + .proc_handler = &proc_dointvec,
> + },
> + {
> .ctl_name = 0, /* sentinel */
> }
> },
> diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
> index 0711f92..5fd7cf9 100644
> --- a/net/ipv6/exthdrs.c
> +++ b/net/ipv6/exthdrs.c
> @@ -363,10 +363,27 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
> struct inet6_skb_parm *opt = IP6CB(skb);
> struct in6_addr *addr = NULL;
> struct in6_addr daddr;
> + struct inet6_dev *idev;
> int n, i;
> -
> struct ipv6_rt_hdr *hdr;
> struct rt0_hdr *rthdr;
> + int accept_source_route = ipv6_devconf.accept_source_route;
> +
> + if (accept_source_route < 0 ||
> + ((idev = in6_dev_get(skb->dev)) == NULL)) {
> + kfree_skb(skb);
> + return -1;
> + }
> + if (idev->cnf.accept_source_route < 0) {
> + in6_dev_put(idev);
> + kfree_skb(skb);
> + return -1;
> + }
> +
> + if (accept_source_route > idev->cnf.accept_source_route)
> + accept_source_route = idev->cnf.accept_source_route;
> +
> + in6_dev_put(idev);
>
> if (!pskb_may_pull(skb, (skb->h.raw-skb->data)+8) ||
> !pskb_may_pull(skb, (skb->h.raw-skb->data)+((skb->h.raw[1]+1)<<3))) {
> @@ -378,6 +395,22 @@ static int ipv6_rthdr_rcv(struct sk_buff **skbp)
>
> hdr = (struct ipv6_rt_hdr *) skb->h.raw;
>
> + switch (hdr->type) {
> +#ifdef CONFIG_IPV6_MIP6
> + break;
> +#endif
> + case IPV6_SRCRT_TYPE_0:
> + if (accept_source_route > 0)
> + break;
> + kfree_skb(skb);
> + return -1;
> + default:
> + IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
> + IPSTATS_MIB_INHDRERRORS);
> + icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
> + return -1;
> + }
> +
> if (ipv6_addr_is_multicast(&skb->nh.ipv6h->daddr) ||
> skb->pkt_type != PACKET_HOST) {
> IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
> @@ -435,11 +468,6 @@ looped_back:
> }
> break;
> #endif
> - default:
> - IP6_INC_STATS_BH(ip6_dst_idev(skb->dst),
> - IPSTATS_MIB_INHDRERRORS);
> - icmpv6_param_prob(skb, ICMPV6_HDR_FIELD, (&hdr->type) - skb->nh.raw);
> - return -1;
> }
>
> /*
> --
> 1.4.4.2
>
>
--
Ubuntu: http://www.ubuntu.com/
Linux1394: http://www.linux1394.org/
More information about the kernel-team
mailing list