From nobody@FreeBSD.org  Thu Oct 14 10:37:46 2010
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34])
	by hub.freebsd.org (Postfix) with ESMTP id D1551106564A
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Oct 2010 10:37:46 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from www.freebsd.org (www.freebsd.org [IPv6:2001:4f8:fff6::21])
	by mx1.freebsd.org (Postfix) with ESMTP id A555E8FC0C
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Oct 2010 10:37:46 +0000 (UTC)
Received: from www.freebsd.org (localhost [127.0.0.1])
	by www.freebsd.org (8.14.3/8.14.3) with ESMTP id o9EAbju7013164
	for <freebsd-gnats-submit@FreeBSD.org>; Thu, 14 Oct 2010 10:37:45 GMT
	(envelope-from nobody@www.freebsd.org)
Received: (from nobody@localhost)
	by www.freebsd.org (8.14.3/8.14.3/Submit) id o9EAbj7v013153;
	Thu, 14 Oct 2010 10:37:45 GMT
	(envelope-from nobody)
Message-Id: <201010141037.o9EAbj7v013153@www.freebsd.org>
Date: Thu, 14 Oct 2010 10:37:45 GMT
From: Martin Beran <mb@tns.cz>
To: freebsd-gnats-submit@FreeBSD.org
Subject: [patch] IPsec SPD rule does not match GIF with IPv6 addresses
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         151449
>Category:       kern
>Synopsis:       [patch] IPsec SPD rule does not match GIF with IPv6 addresses
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    gnn
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Oct 14 10:40:04 UTC 2010
>Closed-Date:    
>Last-Modified:  Sun May 18 05:00:46 UTC 2014
>Originator:     Martin Beran
>Release:        7.1-RELEASE-p13
>Organization:
Trusted Network Solutions, a. s.
>Environment:
FreeBSD builder764.pha.tns.cz 7.1-RELEASE-p13 FreeBSD 7.1-RELEASE-p13 #18: Thu Oct 14 10:08:50 CEST 2010     root@builder764.pha.tns.cz:/usr/obj/usr/src/sys/KERNUN.amd64  amd64
>Description:
I want to secure a GIF tunnel by IPsec. I have a GIF interface with an inet6 address and also inet6 tunnel addresses. I configure Racoon add the following rules to SPD by setkey:
spdadd 2001:470:1f0b:102::1/128 2001:470:1f0b:102:20c:29ff:feed:ce83/128 41 -P in ipsec esp/transport//require;
spdadd 2001:470:1f0b:102:20c:29ff:feed:ce83/128 2001:470:1f0b:102::1/128 41 -P out ipsec esp/transport//require;

Now the first packet sent via the tunnel should establish an SA and the tunneled traffic should be encrypted by IPsec (in transport mode). But the packets are sent unencrypted, because the SPD entry does not match.

I first tried it on 7.1, but the related kernel code is the same in 8.1. The bug is caused by searching for the upper layer protocol number in the GIF packet (IPv6 packet encapsulated in another IPv6 packet) in functions ipsec6_get_ulp(), ip6_lasthdr(), and ip6_nexthdr(). Instead of stopping on the header of the encapsulated packet and returning IPPROTO_IPV6 (41), the search continues into the encapsulated packet and returns its payload protocol number.
>How-To-Repeat:
Configure a GIF tunnel with both inner and outer addresses being IPv6. Set an IPsec policy that secures the tunnel by matching the upper layer protocol 41 (IPv6). This policy will never match and the communication will not be secured by IPsec.
>Fix:
Apply the attached patch and rebuild the kernel.

Patch attached with submission follows:

--- /usr/src/sys/netinet6/ip6_input.c	2010-06-14 04:09:06.000000000 +0200
+++ /home/beran/tmp/i	2010-10-14 12:33:24.000000000 +0200
@@ -1601,8 +1601,12 @@ ip6_lasthdr(struct mbuf *m, int off, int
 			return newoff;
 
 		off = newoff;
 		proto = *nxtp;
+		/* IPv6-in-IPv6 encapsulation (GIF), the second IPv6 header is
+		 * a payload, do not continue to it. */
+		if (proto == IPPROTO_IPV6)
+			return off;
 	}
 }
 
 struct ip6aux *


>Release-Note:
>Audit-Trail:
Responsible-Changed-From-To: freebsd-bugs->bz 
Responsible-Changed-By: bz 
Responsible-Changed-When: Thu Oct 14 10:53:28 UTC 2010 
Responsible-Changed-Why:  
Take for discussion of the right solution. 

http://www.freebsd.org/cgi/query-pr.cgi?pr=151449 

From: "Bjoern A. Zeeb" <bz@FreeBSD.org>
To: bug-followup@FreeBSD.org, mb@tns.cz
Cc:  
Subject: Re: kern/151449: [patch] IPsec SPD rule does not match GIF with IPv6
 addresses
Date: Thu, 14 Oct 2010 10:53:12 +0000 (UTC)

 Hi,
 
 unfortunately I fear that the proposed patch will break a couple of
 other places.  Maybe we'd need to rework ipsec6_get_ulp() doing the
 iteration there?
 
 /bz
 
 -- 
 Bjoern A. Zeeb                              Welcome a new stage of life.

From: Martin Beran <mb@tns.cz>
To: "Bjoern A. Zeeb" <bz@FreeBSD.org>
Cc: bug-followup@FreeBSD.org
Subject: Re: kern/151449: [patch] IPsec SPD rule does not match GIF with IPv6
 addresses
Date: Thu, 14 Oct 2010 13:28:04 +0200

 Dne 10/14/10 12:53, Bjoern A. Zeeb napsal(a):
 
 Hi,
 
 > unfortunately I fear that the proposed patch will break a couple of
 
 this was just a quick fix, I mainly wanted to confirm my idea about what
 caused the bug. But, on the other hand, ip6_lasthdr() is called on just
 two places in kernel sources. One is in ipsec6_get_ulp(), the other one
 is in icmp6_error(). And I think that ip6_lasthdr() should find the end
 of IPv6 extension headers chain. IPPROTO_IPV6 does not belong to the
 chain. It is either the first (basic IPv6) header, or the payload type
 (when doing encapsulation).
 
 > other places.  Maybe we'd need to rework ipsec6_get_ulp() doing the
 > iteration there?
 
 Maybe this would be a safer fix.
 
 -- 
 Martin Beran
 
 Senior Developer
 
 Trusted Network Solutions, a.s.
 mobil: +420 603 820 932
 [ www.tns.cz ]
Responsible-Changed-From-To: bz->gnn 
Responsible-Changed-By: bz 
Responsible-Changed-When: Sun May 18 05:00:38 UTC 2014 
Responsible-Changed-Why:  
I shall not use bugzilla (at least until we will have a CLI). 

http://www.freebsd.org/cgi/query-pr.cgi?pr=151449 
>Unformatted:
