Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1a98d05f authored by YOSHIFUJI Hideaki's avatar YOSHIFUJI Hideaki Committed by David S. Miller
Browse files

ipv6 RAW: Disallow IPPROTO_IPV6-level IPV6_CHECKSUM socket option on ICMPv6 sockets.



RFC3542 tells that IPV6_CHECKSUM socket option in the IPPROTO_IPV6
level is not allowed on ICMPv6 sockets.  IPPROTO_RAW level
IPV6_CHECKSUM socket option (a Linux extension) is still allowed.

Signed-off-by: default avatarYOSHIFUJI Hideaki <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 8d390efd
Loading
Loading
Loading
Loading
+18 −0
Original line number Original line Diff line number Diff line
@@ -971,6 +971,19 @@ static int do_rawv6_setsockopt(struct sock *sk, int level, int optname,


	switch (optname) {
	switch (optname) {
		case IPV6_CHECKSUM:
		case IPV6_CHECKSUM:
			if (inet_sk(sk)->num == IPPROTO_ICMPV6 &&
			    level == IPPROTO_IPV6) {
				/*
				 * RFC3542 tells that IPV6_CHECKSUM socket
				 * option in the IPPROTO_IPV6 level is not
				 * allowed on ICMPv6 sockets.
				 * If you want to set it, use IPPROTO_RAW
				 * level IPV6_CHECKSUM socket option
				 * (Linux extension).
				 */
				return -EINVAL;
			}

			/* You may get strange result with a positive odd offset;
			/* You may get strange result with a positive odd offset;
			   RFC2292bis agrees with me. */
			   RFC2292bis agrees with me. */
			if (val > 0 && (val&1))
			if (val > 0 && (val&1))
@@ -1046,6 +1059,11 @@ static int do_rawv6_getsockopt(struct sock *sk, int level, int optname,


	switch (optname) {
	switch (optname) {
	case IPV6_CHECKSUM:
	case IPV6_CHECKSUM:
		/*
		 * We allow getsockopt() for IPPROTO_IPV6-level
		 * IPV6_CHECKSUM socket option on ICMPv6 sockets
		 * since RFC3542 is silent about it.
		 */
		if (rp->checksum == 0)
		if (rp->checksum == 0)
			val = -1;
			val = -1;
		else
		else