From: Brian Haley Date: Thu, 13 Nov 2008 06:59:21 +0000 (-0800) Subject: ipv6: routing header fixes X-Git-Url: https://git.karo-electronics.de/?a=commitdiff_plain;h=6e093d9dfffc9a02cd54d36904c62f705f09900a;p=linux-beck.git ipv6: routing header fixes This patch fixes two bugs: 1. setsockopt() of anything but a Type 2 routing header should return EINVAL instead of EPERM. Noticed by Shan Wei (shanwei@cn.fujitsu.com). 2. setsockopt()/sendmsg() of a Type 2 routing header with invalid length or segments should return EINVAL. These values are statically fixed in RFC 3775, unlike the variable Type 0 was. Signed-off-by: Brian Haley Signed-off-by: David S. Miller --- diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 410046a8cc91..e44deb8d4df2 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -661,6 +661,11 @@ int datagram_send_ctl(struct net *net, switch (rthdr->type) { #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) case IPV6_SRCRT_TYPE_2: + if (rthdr->hdrlen != 2 || + rthdr->segments_left != 1) { + err = -EINVAL; + goto exit_f; + } break; #endif default: diff --git a/net/ipv6/ipv6_sockglue.c b/net/ipv6/ipv6_sockglue.c index 4e5eac301f91..2aa294be0c79 100644 --- a/net/ipv6/ipv6_sockglue.c +++ b/net/ipv6/ipv6_sockglue.c @@ -366,11 +366,16 @@ static int do_ipv6_setsockopt(struct sock *sk, int level, int optname, } /* routing header option needs extra check */ + retv = -EINVAL; if (optname == IPV6_RTHDR && opt && opt->srcrt) { struct ipv6_rt_hdr *rthdr = opt->srcrt; switch (rthdr->type) { #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE) case IPV6_SRCRT_TYPE_2: + if (rthdr->hdrlen != 2 || + rthdr->segments_left != 1) + goto sticky_done; + break; #endif default: