[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