diff mbox

ipv6: routing header fixes

Message ID 491A031F.40901@hp.com
State Accepted, archived
Delegated to: David Miller
Headers show

Commit Message

Brian Haley Nov. 11, 2008, 10:11 p.m. UTC
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 <brian.haley@hp.com>

Comments

David Miller Nov. 13, 2008, 6:59 a.m. UTC | #1
From: Brian Haley <brian.haley@hp.com>
Date: Tue, 11 Nov 2008 17:11:43 -0500

> 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 <brian.haley@hp.com>

Looks good, applied, thanks Brian.
--
To unsubscribe from this list: send the line "unsubscribe netdev" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c
index 410046a..e44deb8 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 4e5eac3..2aa294b 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: