netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v2 net-next] ipv6: Send ICMP errors for exceeding extension header limits
@ 2019-06-03 15:47 Tom Herbert
  2019-06-06  0:11 ` David Miller
  0 siblings, 1 reply; 3+ messages in thread
From: Tom Herbert @ 2019-06-03 15:47 UTC (permalink / raw)
  To: davem, netdev; +Cc: Tom Herbert

Define constants and add support to send ICMPv6 Parameter Problem
errors as specified in draft-ietf-6man-icmp-limits-02.

The following parameter problem errors are sent when processing
Hop-by-Hop or Destination Options:

   * ICMPV6_TOOBIG_OPTION
      - Sent if the length of an option exceeds the extent of the
        extension header.
      - Sent if a packet exceeding the padding limit is received
        (more than seven consecutive bytes of padding).

   * ICMPV6_TOOMANY_OPTIONS
      - Sent if a packet is received and HBH option count exceeds
        ipv6.sysctl.max_hbh_opts_cnt or DO option count exceeds
        ipv6.sysctl.max_dst_opts_cnt.

   * ICMPV6_EXTHDR_TOOBIG
      - Sent if length of HBH EH exceeds ipv6.sysctl.max_hbh_opts_len
        or length of DO EH exceeds ipv6.sysctl.max_dst_opts_len.
      - Sent if the length of an extension header exceeds the
        extent of the packet.

   * ICMPV6_HDR_FIELD
      - Sent if a data byte in PADN is non-zero

Signed-off-by: Tom Herbert <tom@quantonium.net>
---
 include/uapi/linux/icmpv6.h |  6 ++++++
 net/ipv6/exthdrs.c          | 50 +++++++++++++++++++++++++++++++++++++--------
 2 files changed, 48 insertions(+), 8 deletions(-)

diff --git a/include/uapi/linux/icmpv6.h b/include/uapi/linux/icmpv6.h
index 2622b5a..966279b 100644
--- a/include/uapi/linux/icmpv6.h
+++ b/include/uapi/linux/icmpv6.h
@@ -124,6 +124,7 @@ struct icmp6hdr {
 #define ICMPV6_PORT_UNREACH		4
 #define ICMPV6_POLICY_FAIL		5
 #define ICMPV6_REJECT_ROUTE		6
+#define ICMPV6_SRCRT_ERR		7
 
 /*
  *	Codes for Time Exceeded
@@ -137,6 +138,11 @@ struct icmp6hdr {
 #define ICMPV6_HDR_FIELD		0
 #define ICMPV6_UNK_NEXTHDR		1
 #define ICMPV6_UNK_OPTION		2
+#define ICMPV6_FIRST_FRAG_INCOMP	3
+#define ICMPV6_EXTHDR_TOOBIG		4
+#define ICMPV6_EXTHDR_CHAINLONG		5
+#define ICMPV6_TOOMANY_OPTIONS		6
+#define ICMPV6_TOOBIG_OPTION		7
 
 /*
  *	constants for (set|get)sockopt
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 20291c2..05061f4 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -131,8 +131,11 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
 		max_count = -max_count;
 	}
 
-	if (skb_transport_offset(skb) + len > skb_headlen(skb))
+	if (skb_transport_offset(skb) + len > skb_headlen(skb)) {
+		icmpv6_send(skb, ICMPV6_PARAMPROB,
+			    ICMPV6_EXTHDR_TOOBIG, skb_transport_offset(skb));
 		goto bad;
+	}
 
 	off += 2;
 	len -= 2;
@@ -145,8 +148,11 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
 		case IPV6_TLV_PAD1:
 			optlen = 1;
 			padlen++;
-			if (padlen > 7)
+			if (padlen > 7) {
+				icmpv6_send(skb, ICMPV6_PARAMPROB,
+					    ICMPV6_TOOBIG_OPTION, off);
 				goto bad;
+			}
 			break;
 
 		case IPV6_TLV_PADN:
@@ -156,25 +162,37 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
 			 * See also RFC 4942, Section 2.1.9.5.
 			 */
 			padlen += optlen;
-			if (padlen > 7)
+			if (padlen > 7) {
+				icmpv6_send(skb, ICMPV6_PARAMPROB,
+					    ICMPV6_TOOBIG_OPTION, off);
 				goto bad;
+			}
 			/* RFC 4942 recommends receiving hosts to
 			 * actively check PadN payload to contain
 			 * only zeroes.
 			 */
 			for (i = 2; i < optlen; i++) {
-				if (nh[off + i] != 0)
+				if (nh[off + i] != 0) {
+					icmpv6_send(skb, ICMPV6_PARAMPROB,
+						    ICMPV6_HDR_FIELD, off + i);
 					goto bad;
+				}
 			}
 			break;
 
 		default: /* Other TLV code so scan list */
-			if (optlen > len)
+			if (optlen > len) {
+				icmpv6_send(skb, ICMPV6_PARAMPROB,
+					    ICMPV6_TOOBIG_OPTION, off);
 				goto bad;
+			}
 
 			tlv_count++;
-			if (tlv_count > max_count)
+			if (tlv_count > max_count) {
+				icmpv6_send(skb, ICMPV6_PARAMPROB,
+					    ICMPV6_TOOMANY_OPTIONS, off);
 				goto bad;
+			}
 
 			for (curr = procs; curr->type >= 0; curr++) {
 				if (curr->type == nh[off]) {
@@ -200,6 +218,8 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
 	if (len == 0)
 		return true;
 bad:
+	__IP6_INC_STATS(dev_net(skb->dev), __in6_dev_get(skb->dev),
+			IPSTATS_MIB_INHDRERRORS);
 	kfree_skb(skb);
 	return false;
 }
@@ -300,8 +320,15 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
 	}
 
 	extlen = (skb_transport_header(skb)[1] + 1) << 3;
-	if (extlen > net->ipv6.sysctl.max_dst_opts_len)
+	if (extlen > net->ipv6.sysctl.max_dst_opts_len) {
+		icmpv6_send(skb, ICMPV6_PARAMPROB,
+			    ICMPV6_EXTHDR_TOOBIG,
+			    skb_network_header_len(skb) +
+				net->ipv6.sysctl.max_dst_opts_len);
+		__IP6_INC_STATS(dev_net(dst->dev), idev,
+				IPSTATS_MIB_INHDRERRORS);
 		goto fail_and_free;
+	}
 
 	opt->lastopt = opt->dst1 = skb_network_header_len(skb);
 #if IS_ENABLED(CONFIG_IPV6_MIP6)
@@ -843,8 +870,15 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
 	}
 
 	extlen = (skb_transport_header(skb)[1] + 1) << 3;
-	if (extlen > net->ipv6.sysctl.max_hbh_opts_len)
+	if (extlen > net->ipv6.sysctl.max_hbh_opts_len) {
+		__IP6_INC_STATS(net, __in6_dev_get(skb->dev),
+				IPSTATS_MIB_INHDRERRORS);
+		icmpv6_send(skb, ICMPV6_PARAMPROB,
+			    ICMPV6_EXTHDR_TOOBIG,
+			skb_network_header_len(skb) +
+				net->ipv6.sysctl.max_hbh_opts_len);
 		goto fail_and_free;
+	}
 
 	opt->flags |= IP6SKB_HOPBYHOP;
 	if (ip6_parse_tlv(tlvprochopopt_lst, skb,
-- 
2.7.4


^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 net-next] ipv6: Send ICMP errors for exceeding extension header limits
  2019-06-03 15:47 [PATCH v2 net-next] ipv6: Send ICMP errors for exceeding extension header limits Tom Herbert
@ 2019-06-06  0:11 ` David Miller
  2019-06-06  1:03   ` Tom Herbert
  0 siblings, 1 reply; 3+ messages in thread
From: David Miller @ 2019-06-06  0:11 UTC (permalink / raw)
  To: tom; +Cc: netdev, tom

From: Tom Herbert <tom@herbertland.com>
Date: Mon,  3 Jun 2019 08:47:47 -0700

> Define constants and add support to send ICMPv6 Parameter Problem
> errors as specified in draft-ietf-6man-icmp-limits-02.

Tom, I've kinda had enough of this pushing your agenda by trying to
add support for ipv6 features that are in draft state with the IETF
and you are the author of said drafts.

I'm not applying this stuff, sorry.

^ permalink raw reply	[flat|nested] 3+ messages in thread

* Re: [PATCH v2 net-next] ipv6: Send ICMP errors for exceeding extension header limits
  2019-06-06  0:11 ` David Miller
@ 2019-06-06  1:03   ` Tom Herbert
  0 siblings, 0 replies; 3+ messages in thread
From: Tom Herbert @ 2019-06-06  1:03 UTC (permalink / raw)
  To: David Miller; +Cc: Tom Herbert, Linux Kernel Network Developers

On Wed, Jun 5, 2019 at 5:11 PM David Miller <davem@davemloft.net> wrote:
>
> From: Tom Herbert <tom@herbertland.com>
> Date: Mon,  3 Jun 2019 08:47:47 -0700
>
> > Define constants and add support to send ICMPv6 Parameter Problem
> > errors as specified in draft-ietf-6man-icmp-limits-02.
>
> Tom, I've kinda had enough of this pushing your agenda by trying to
> add support for ipv6 features that are in draft state with the IETF
> and you are the author of said drafts.
>
I'm sorry, I had no idea that there were criteria that we had to
follow with respect to patches and IETF. Please specify the criteria,
which I will assume that apply to everyone and not to just me, so that
we can avoid further instances of wasted time.

Thanks,
Tom

> I'm not applying this stuff, sorry.

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2019-06-06  1:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-06-03 15:47 [PATCH v2 net-next] ipv6: Send ICMP errors for exceeding extension header limits Tom Herbert
2019-06-06  0:11 ` David Miller
2019-06-06  1:03   ` Tom Herbert

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).