lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1559933708-13947-4-git-send-email-tom@quantonium.net>
Date:   Fri,  7 Jun 2019 11:55:06 -0700
From:   Tom Herbert <tom@...bertland.com>
To:     davem@...emloft.net, netdev@...r.kernel.org, dlebrun@...gle.com
Cc:     Tom Herbert <tom@...ntonium.net>
Subject: [RFC v2 PATCH 3/5] ipv6: Paramterize TLV parsing

Add parameters to ip6_parse_tlv that will allow leveraging the function
for parsing segment routing TLVs. The new parameters are offset of
TLVs, length of the TLV block, and a function that is called in the case
of an unrecognized option.

Signed-off-by: Tom Herbert <tom@...ntonium.net>
---
 net/ipv6/exthdrs.c | 35 ++++++++++++++++++++++++-----------
 1 file changed, 24 insertions(+), 11 deletions(-)

diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 20291c2..a394d20 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -112,15 +112,26 @@ static bool ip6_tlvopt_unknown(struct sk_buff *skb, int optoff,
 	return false;
 }
 
-/* Parse tlv encoded option header (hop-by-hop or destination) */
+/* Parse tlv encoded option header (hop-by-hop or destination)
+ *
+ * Arguments:
+ *   procs - TLV proc structure
+ *   skb - skbuff containing TLVs
+ *   max_count - absolute value is maximum nuber of TLVs. If less than zero
+ *		 then unknown TLVs are disallowed regardless of disposition
+ *		 indicated by TLV type
+ *   off - offset of first TLV relative to the first byte of the extension
+ *	   header which is transport header of the skb
+ *   len - length of TLV block
+ *   unknown_opt - function called when unknown option is encountered
+ */
 
 static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
-			  struct sk_buff *skb,
-			  int max_count)
+			  struct sk_buff *skb, int max_count, int off, int len,
+			  bool (*unknown_opt)(struct sk_buff *skb, int optoff,
+					      bool disallow_unknowns))
 {
-	int len = (skb_transport_header(skb)[1] + 1) << 3;
 	const unsigned char *nh = skb_network_header(skb);
-	int off = skb_network_header_len(skb);
 	const struct tlvtype_proc *curr;
 	bool disallow_unknowns = false;
 	int tlv_count = 0;
@@ -131,11 +142,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) + off + len > skb_headlen(skb))
 		goto bad;
 
-	off += 2;
-	len -= 2;
+	/* Offset relative to network header for parse loop */
+	off += skb_network_header_len(skb);
 
 	while (len > 0) {
 		int optlen = nh[off + 1] + 2;
@@ -187,7 +198,7 @@ static bool ip6_parse_tlv(const struct tlvtype_proc *procs,
 				}
 			}
 			if (curr->type < 0 &&
-			    !ip6_tlvopt_unknown(skb, off, disallow_unknowns))
+			    !unknown_opt(skb, off, disallow_unknowns))
 				return false;
 
 			padlen = 0;
@@ -309,7 +320,8 @@ static int ipv6_destopt_rcv(struct sk_buff *skb)
 #endif
 
 	if (ip6_parse_tlv(tlvprocdestopt_lst, skb,
-			  init_net.ipv6.sysctl.max_dst_opts_cnt)) {
+			  init_net.ipv6.sysctl.max_dst_opts_cnt,
+			  2, extlen - 2, ip6_tlvopt_unknown)) {
 		skb->transport_header += extlen;
 		opt = IP6CB(skb);
 #if IS_ENABLED(CONFIG_IPV6_MIP6)
@@ -848,7 +860,8 @@ int ipv6_parse_hopopts(struct sk_buff *skb)
 
 	opt->flags |= IP6SKB_HOPBYHOP;
 	if (ip6_parse_tlv(tlvprochopopt_lst, skb,
-			  init_net.ipv6.sysctl.max_hbh_opts_cnt)) {
+			  init_net.ipv6.sysctl.max_hbh_opts_cnt,
+			  2, extlen - 2, ip6_tlvopt_unknown)) {
 		skb->transport_header += extlen;
 		opt = IP6CB(skb);
 		opt->nhoff = sizeof(struct ipv6hdr);
-- 
2.7.4

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ