Subject: kern/22715: Port-specific TCP IPsec security policies don't work
To: None <gnats-bugs@gnats.netbsd.org>
From: None <michael.eriksson@era-t.ericsson.se>
List: netbsd-bugs
Date: 09/07/2003 23:18:38
>Number: 22715
>Category: kern
>Synopsis: Port-specific TCP IPsec security policies don't work
>Confidential: no
>Severity: serious
>Priority: medium
>Responsible: kern-bug-people
>State: open
>Class: sw-bug
>Submitter-Id: net
>Arrival-Date: Sun Sep 07 21:19:00 UTC 2003
>Closed-Date:
>Last-Modified:
>Originator: Michael Eriksson
>Release: NetBSD 1.6X
>Organization:
Ericsson Research
>Environment:
>Description:
It is sometimes useful to have IPsec security policies that is just
for a particular transport protocol port, e.g., to protect NFS
traffic. Due to a kernel bug, port-specific TCP policies don't work.
>How-To-Repeat:
datan$ setkey -f - <<EOF
spdadd 0.0.0.0/0[any] 10.11.0.0/16[2049] any
-P out ipsec esp/transport//require;
spdadd 10.11.0.0/16[2049] 0.0.0.0/0[any] any
-P in ipsec esp/transport//require;
EOF
datan$ telnet 10.11.0.3 2049
Use tcpdump to see the traffic go unencrypted.
>Fix:
The basic problem is that the IPsec policy is chosen very early, long
before ip_output() is called. Early in tcp_output(), tcp_segsize() is
called. tcp_segsize() indirectly uses tp->t_template to pick a
security policy (which is cached). tp->t_template's IP header length
is not initialised, which makes ipsec4_get_ulp() read the port numbers
from the wrong place in memory (at the start of the IP header).
Index: tcp_subr.c
===================================================================
RCS file: /cvsroot/src/sys/netinet/tcp_subr.c,v
retrieving revision 1.150
diff -u -r1.150 tcp_subr.c
--- tcp_subr.c 2003/08/22 22:27:07 1.150
+++ tcp_subr.c 2003/09/07 20:58:12
@@ -462,6 +462,7 @@
{
struct ipovly *ipov;
mtod(m, struct ip *)->ip_v = 4;
+ mtod(m, struct ip *)->ip_hl = hlen >> 2;
ipov = mtod(m, struct ipovly *);
ipov->ih_pr = IPPROTO_TCP;
ipov->ih_len = htons(sizeof(struct tcphdr));
>Release-Note:
>Audit-Trail:
>Unformatted: