Subject: kern/36051: Incorect handling of cached SPs in FAST_IPSEC]
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Karl Knutsson <karl.knutsson@ericsson.com>
List: netbsd-bugs
Date: 03/21/2007 15:30:00
>Number: 36051
>Category: kern
>Synopsis: Incorect handling of cached SPs in FAST_IPSEC
>Confidential: no
>Severity: non-critical
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Wed Mar 21 15:30:00 +0000 2007
>Originator: Karl Knutsson <karl.knutsson@ericsson.com>
>Release: NetBSD 3.0
>Organization:
LM Ericsson
>Environment:
System: System: NetBSD zuul 3.0.0_STABLE NetBSD 3.0.0_STABLE (SPEED) #0: Mon Sep 18 16:59:06 CEST 2006
Architecture: i386
Machine: i386
>Description:
Incorrect usage of cached policies on unconnected sockets may result in that
the wrong policy is applied to a packet. The fact that a packet matches
a cached rule isn't enough reason to apply it since there might be policies
with higher priority, e.i. a policy that where inserted before the cached
policy, that matches the packet.
>How-To-Repeat:
Insert the following policies. 192.168.66.2 is the address of a local interface
on the machine. Enable the udp echo server in inetd.conf
# cat setkey.conf
spdadd 192.168.70.1[1234] 192.168.66.2 any -P in none;
spdadd 192.168.70.0/24 192.168.66.2 any -P in discard;
# setkey -f setkey.conf
# setkey -DP
192.168.70.1[1234] 192.168.66.2[any] any
in none
spid=1 seq=2 pid=108
refcnt=1
192.168.70.0/24[any] 192.168.66.2[any] any
in discard
spid=2 seq=1 pid=108
refcnt=1
Send a UDP packet from 192.168.70.1[1234] to 192.168.66.2[7].
tcpdump will display the following (expected) output:
14:28:59.460960 IP 192.168.70.1.1234 > 192.168.66.2.7: UDP, length: 64
14:28:59.461152 IP 192.168.66.2.7 > 192.168.70.1.1234: UDP, length: 64
Next send a packet from an address that will get blocked by the second
policy.
tcpdump displays:
14:31:20.480938 IP 192.168.70.2.1234 > 192.168.66.2.7: UDP, length: 64
14:31:20.481035 IP 192.168.66.2 > 192.168.70.2: icmp 36: host 192.168.66.2 unreachable - admin prohibited filter
Finally send a packet that should match the first policy again, that is
from 192.168.70.1[1234].
tcpdump shows that cached policy of the previous packet is applied rather than
the first policy, which has a higher priorioty.
14:33:14.172468 IP 192.168.70.1.1234 > 192.168.66.2.7: UDP, length: 64
14:33:14.172565 IP 192.168.66.2 > 192.168.70.1: icmp 36: host 192.168.66.2 unreachable - admin prohibited filter
>Fix:
Index: ipsec.c
===================================================================
RCS file: /cvsroot/src/sys/netipsec/ipsec.c,v
retrieving revision 1.15
diff -u -r1.15 ipsec.c
--- ipsec.c 26 Feb 2005 22:45:13 -0000 1.15
+++ ipsec.c 16 Mar 2007 09:48:16 -0000
@@ -275,13 +275,16 @@
return NULL;
if (ipsec_setspidx(m, &spidx, 1) != 0)
return NULL;
+
+ /*
+ * We have to make an exact match here since the cached rule
+ * might have lower priority than a rule that would otherwise
+ * have matched the packet.
+ */
if (bcmp(&pcbsp->sp_cache[dir].cacheidx, &spidx,
- sizeof(spidx))) {
- if (!key_cmpspidx_withmask(&pcbsp->sp_cache[dir].cachesp->spidx,
- &spidx))
- return NULL;
- pcbsp->sp_cache[dir].cacheidx = spidx;
- }
+ sizeof(spidx)))
+ return NULL;
+
} else {
/*
* The pcb is connected, and the L4 code is sure that: