netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 16/17] calipso: Add validation of CALIPSO option.
@ 2015-12-22 11:46 Huw Davies
  2015-12-22 13:50 ` Hannes Frederic Sowa
  0 siblings, 1 reply; 5+ messages in thread
From: Huw Davies @ 2015-12-22 11:46 UTC (permalink / raw)
  To: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-security-module-u79uwXL29TY76Z2rM5mHXA,
	selinux-+05T5uksL2qpZYMLLGbcSA

We check lengths, checksum and the DOI.  We leave checking of the
level and categories for the socket layer.

Signed-off-by: Huw Davies <huw-PJ7GQ4yptbsswetKESUqMA@public.gmane.org>
---
 include/net/calipso.h |  6 ++++++
 net/ipv6/calipso.c    | 43 +++++++++++++++++++++++++++++++++++++++++++
 net/ipv6/exthdrs.c    | 27 +++++++++++++++++++++++++++
 3 files changed, 76 insertions(+)

diff --git a/include/net/calipso.h b/include/net/calipso.h
index ad4d653..99df89b 100644
--- a/include/net/calipso.h
+++ b/include/net/calipso.h
@@ -65,6 +65,7 @@ struct calipso_doi {
 #ifdef CONFIG_NETLABEL
 int __init calipso_init(void);
 void calipso_exit(void);
+bool calipso_validate(const struct sk_buff *skb, const unsigned char *option);
 #else
 static inline int __init calipso_init(void)
 {
@@ -74,6 +75,11 @@ static inline int __init calipso_init(void)
 static inline void calipso_exit(void)
 {
 }
+static inline bool calipso_validate(const struct sk_buff *skb,
+				    const unsigned char *option)
+{
+	return true;
+}
 #endif /* CONFIG_NETLABEL */
 
 #endif /* _CALIPSO_H */
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
index a91d71d..f3b7c43 100644
--- a/net/ipv6/calipso.c
+++ b/net/ipv6/calipso.c
@@ -315,6 +315,49 @@ doi_walk_return:
 }
 
 /**
+ * calipso_validate - Validate a CALIPSO option
+ * @skb: the packet
+ * @option: the start of the option
+ *
+ * Description:
+ * This routine is called to validate a CALIPSO option.
+ * If the option is valid then a zero value is returned.  If the
+ * option is invalid then a non-zero value is returned and
+ * representing the offset to the offending portion of the option.
+ *
+ * The caller should have already checked that the length of the
+ * option (including the TLV header) is >= 10 and that the catmap
+ * length is consistent with the option length.
+ *
+ * We leave checks on the level and categories to the socket layer.
+ */
+bool calipso_validate(const struct sk_buff *skb, const unsigned char *option)
+{
+	struct calipso_doi *doi_def;
+	int ret_val;
+	u16 crc, len = option[1] + 2;
+	static const u8 zero[2];
+
+	/* The original CRC runs over the option including the TLV header
+	 * with the CRC-16 field (at offset 8) zeroed out.
+	 */
+	crc = crc_ccitt(0xffff, option, 8);
+	crc = crc_ccitt(crc, zero, sizeof(zero));
+	if (len > 10)
+		crc = crc_ccitt(crc, option + 10, len - 10);
+	crc = ~crc;
+	if (option[8] != (crc & 0xff) || option[9] != ((crc >> 8) & 0xff))
+		return false;
+
+	rcu_read_lock();
+	doi_def = calipso_doi_search(get_unaligned_be32(option + 2));
+	ret_val = !!doi_def;
+	rcu_read_unlock();
+
+	return ret_val;
+}
+
+/**
  * calipso_map_cat_hton - Perform a category mapping from host to network
  * @doi_def: the DOI definition
  * @secattr: the security attributes
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index e87c89b..3dc1d15 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -43,6 +43,7 @@
 #include <net/ndisc.h>
 #include <net/ip6_route.h>
 #include <net/addrconf.h>
+#include <net/calipso.h>
 #if IS_ENABLED(CONFIG_IPV6_MIP6)
 #include <net/xfrm.h>
 #endif
@@ -603,6 +604,28 @@ drop:
 	return false;
 }
 
+/* CALIPSO RFC 5570 */
+
+static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
+{
+	const unsigned char *nh = skb_network_header(skb);
+
+	if (nh[optoff + 1] < 8)
+		goto drop;
+
+	if (nh[optoff + 6] * 4 + 8 > nh[optoff + 1])
+		goto drop;
+
+	if (!calipso_validate(skb, nh + optoff))
+		goto drop;
+
+	return true;
+
+drop:
+	kfree_skb(skb);
+	return false;
+}
+
 static const struct tlvtype_proc tlvprochopopt_lst[] = {
 	{
 		.type	= IPV6_TLV_ROUTERALERT,
@@ -612,6 +635,10 @@ static const struct tlvtype_proc tlvprochopopt_lst[] = {
 		.type	= IPV6_TLV_JUMBO,
 		.func	= ipv6_hop_jumbo,
 	},
+	{
+		.type	= IPV6_TLV_CALIPSO,
+		.func	= ipv6_hop_calipso,
+	},
 	{ -1, }
 };
 
-- 
1.8.0

_______________________________________________
Selinux mailing list
Selinux-+05T5uksL2qpZYMLLGbcSA@public.gmane.org
To unsubscribe, send email to Selinux-leave-+05T5uksL2pAGbPMOrvdOA@public.gmane.org
To get help, send an email containing "help" to Selinux-request-+05T5uksL2pAGbPMOrvdOA@public.gmane.org

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

* Re: [RFC PATCH 16/17] calipso: Add validation of CALIPSO option.
  2015-12-22 11:46 [RFC PATCH 16/17] calipso: Add validation of CALIPSO option Huw Davies
@ 2015-12-22 13:50 ` Hannes Frederic Sowa
  2015-12-22 16:59   ` Huw Davies
  0 siblings, 1 reply; 5+ messages in thread
From: Hannes Frederic Sowa @ 2015-12-22 13:50 UTC (permalink / raw)
  To: Huw Davies, netdev, linux-security-module, selinux; +Cc: Paul Moore

On 22.12.2015 12:46, Huw Davies wrote:
>  
> +/* CALIPSO RFC 5570 */
> +
> +static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
> +{
> +	const unsigned char *nh = skb_network_header(skb);
> +
> +	if (nh[optoff + 1] < 8)
> +		goto drop;
> +
> +	if (nh[optoff + 6] * 4 + 8 > nh[optoff + 1])
> +		goto drop;
> +
> +	if (!calipso_validate(skb, nh + optoff))
> +		goto drop;
> +
> +	return true;
> +
> +drop:
> +	kfree_skb(skb);
> +	return false;
> +}
> +

Formally, if an extension header could not be processed, the packet
should be discarded and an icmp error parameter extension should be
send. I think we shouldn't let those packets pass here.

Thanks,
Hannes

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

* Re: [RFC PATCH 16/17] calipso: Add validation of CALIPSO option.
  2015-12-22 13:50 ` Hannes Frederic Sowa
@ 2015-12-22 16:59   ` Huw Davies
  2015-12-22 21:47     ` Hannes Frederic Sowa
  0 siblings, 1 reply; 5+ messages in thread
From: Huw Davies @ 2015-12-22 16:59 UTC (permalink / raw)
  To: Hannes Frederic Sowa; +Cc: netdev, linux-security-module, selinux, Paul Moore

On Tue, Dec 22, 2015 at 02:50:20PM +0100, Hannes Frederic Sowa wrote:
> On 22.12.2015 12:46, Huw Davies wrote:
> >  
> > +/* CALIPSO RFC 5570 */
> > +
> > +static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
> > +{
> > +	const unsigned char *nh = skb_network_header(skb);
> > +
> > +	if (nh[optoff + 1] < 8)
> > +		goto drop;
> > +
> > +	if (nh[optoff + 6] * 4 + 8 > nh[optoff + 1])
> > +		goto drop;
> > +
> > +	if (!calipso_validate(skb, nh + optoff))
> > +		goto drop;
> > +
> > +	return true;
> > +
> > +drop:
> > +	kfree_skb(skb);
> > +	return false;
> > +}
> > +
> 
> Formally, if an extension header could not be processed, the packet
> should be discarded and an icmp error parameter extension should be
> send. I think we shouldn't let those packets pass here.

Thanks for your comments Hannes, I'm looking into your other
suggestions.

I'm confused about this one.  AFAICS, this will drop packets that we
can't process.  We don't send the icmp error, but I can certainly add
that.  Is that what you mean?

Thanks,
Huw.

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

* Re: [RFC PATCH 16/17] calipso: Add validation of CALIPSO option.
  2015-12-22 16:59   ` Huw Davies
@ 2015-12-22 21:47     ` Hannes Frederic Sowa
  2015-12-22 22:29       ` Huw Davies
  0 siblings, 1 reply; 5+ messages in thread
From: Hannes Frederic Sowa @ 2015-12-22 21:47 UTC (permalink / raw)
  To: Huw Davies; +Cc: netdev, linux-security-module, selinux, Paul Moore

On 22.12.2015 17:59, Huw Davies wrote:
> On Tue, Dec 22, 2015 at 02:50:20PM +0100, Hannes Frederic Sowa wrote:
>> On 22.12.2015 12:46, Huw Davies wrote:
>>>  
>>> +/* CALIPSO RFC 5570 */
>>> +
>>> +static bool ipv6_hop_calipso(struct sk_buff *skb, int optoff)
>>> +{
>>> +	const unsigned char *nh = skb_network_header(skb);
>>> +
>>> +	if (nh[optoff + 1] < 8)
>>> +		goto drop;
>>> +
>>> +	if (nh[optoff + 6] * 4 + 8 > nh[optoff + 1])
>>> +		goto drop;
>>> +
>>> +	if (!calipso_validate(skb, nh + optoff))
>>> +		goto drop;
>>> +
>>> +	return true;
>>> +
>>> +drop:
>>> +	kfree_skb(skb);
>>> +	return false;
>>> +}
>>> +
>>
>> Formally, if an extension header could not be processed, the packet
>> should be discarded and an icmp error parameter extension should be
>> send. I think we shouldn't let those packets pass here.
> 
> Thanks for your comments Hannes, I'm looking into your other
> suggestions.
> 
> I'm confused about this one.  AFAICS, this will drop packets that we
> can't process.  We don't send the icmp error, but I can certainly add
> that.  Is that what you mean?

Actually, the implementation of calipso_validate will accept the packets
because it defaults to return true if we don't compile the module. At
least we should drop the packet if it is not loaded. I am in favor of
adding the parameter problem icmp error. So, yes, I think it should be
added.

Bye,
Hannes

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

* Re: [RFC PATCH 16/17] calipso: Add validation of CALIPSO option.
  2015-12-22 21:47     ` Hannes Frederic Sowa
@ 2015-12-22 22:29       ` Huw Davies
  0 siblings, 0 replies; 5+ messages in thread
From: Huw Davies @ 2015-12-22 22:29 UTC (permalink / raw)
  To: Hannes Frederic Sowa; +Cc: netdev, linux-security-module, selinux, Paul Moore

On Tue, Dec 22, 2015 at 10:47:43PM +0100, Hannes Frederic Sowa wrote:
> On 22.12.2015 17:59, Huw Davies wrote:
> > I'm confused about this one.  AFAICS, this will drop packets that we
> > can't process.  We don't send the icmp error, but I can certainly add
> > that.  Is that what you mean?
> 
> Actually, the implementation of calipso_validate will accept the packets
> because it defaults to return true if we don't compile the module. At
> least we should drop the packet if it is not loaded. I am in favor of
> adding the parameter problem icmp error. So, yes, I think it should be
> added.

Yet the option value is 0x07, i.e. the two highest bits are both zero
which according to:
https://tools.ietf.org/html/rfc2460#section-4.2
means we should just skip it.

https://tools.ietf.org/html/rfc5570#section-5.1.1
reaffirms that.

In terms of sending an icmp on error while validating:
https://tools.ietf.org/html/rfc5570#section-6.2.2
is pretty conservative in that case too.  Most errors
should just be silently dropped.

Huw.

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

end of thread, other threads:[~2015-12-22 22:29 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-12-22 11:46 [RFC PATCH 16/17] calipso: Add validation of CALIPSO option Huw Davies
2015-12-22 13:50 ` Hannes Frederic Sowa
2015-12-22 16:59   ` Huw Davies
2015-12-22 21:47     ` Hannes Frederic Sowa
2015-12-22 22:29       ` Huw Davies

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).