From owner-freebsd-bugs@FreeBSD.ORG Sun Jan 4 04:10:28 2004 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id A916C16A4CF for ; Sun, 4 Jan 2004 04:10:28 -0800 (PST) Received: from freefall.freebsd.org (freefall.freebsd.org [216.136.204.21]) by mx1.FreeBSD.org (Postfix) with ESMTP id A55AC43D54 for ; Sun, 4 Jan 2004 04:10:21 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (gnats@localhost [127.0.0.1]) i04CALFR024441 for ; Sun, 4 Jan 2004 04:10:21 -0800 (PST) (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.12.10/8.12.10/Submit) id i04CALue024440; Sun, 4 Jan 2004 04:10:21 -0800 (PST) (envelope-from gnats) Resent-Date: Sun, 4 Jan 2004 04:10:21 -0800 (PST) Resent-Message-Id: <200401041210.i04CALue024440@freefall.freebsd.org> Resent-From: FreeBSD-gnats-submit@FreeBSD.org (GNATS Filer) Resent-To: freebsd-bugs@FreeBSD.org Resent-Reply-To: FreeBSD-gnats-submit@FreeBSD.org, Richard Wendland Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 4064F16A4CF for ; Sun, 4 Jan 2004 04:03:28 -0800 (PST) Received: from www.freebsd.org (www.freebsd.org [216.136.204.117]) by mx1.FreeBSD.org (Postfix) with ESMTP id 119C943D4C for ; Sun, 4 Jan 2004 04:03:26 -0800 (PST) (envelope-from nobody@FreeBSD.org) Received: from www.freebsd.org (localhost [127.0.0.1]) by www.freebsd.org (8.12.10/8.12.10) with ESMTP id i04C3PdL033276 for ; Sun, 4 Jan 2004 04:03:25 -0800 (PST) (envelope-from nobody@www.freebsd.org) Received: (from nobody@localhost) by www.freebsd.org (8.12.10/8.12.10/Submit) id i04C3P39033275; Sun, 4 Jan 2004 04:03:25 -0800 (PST) (envelope-from nobody) Message-Id: <200401041203.i04C3P39033275@www.freebsd.org> Date: Sun, 4 Jan 2004 04:03:25 -0800 (PST) From: Richard Wendland To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-2.0 Subject: kern/60889: 5.2RC2 - zero IP id change not effective for TCP, detrimental to security/privacy and maybe interoperation X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.1 Precedence: list List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 04 Jan 2004 12:10:28 -0000 >Number: 60889 >Category: kern >Synopsis: 5.2RC2 - zero IP id change not effective for TCP, detrimental to security/privacy and maybe interoperation >Confidential: no >Severity: serious >Priority: high >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Sun Jan 04 04:10:21 PST 2004 >Closed-Date: >Last-Modified: >Originator: Richard Wendland >Release: 5.2-RC2 >Organization: >Environment: FreeBSD dva.in-berlin.de 5.2-RC FreeBSD 5.2-RC #0: Thu Jan 1 21:30:04 CET 2004 root@dva.in-berlin.de:/usr/src/sys/i386/compile/DVA i386 >Description: The src/sys/netinet/ip_output.c Revision 1.189 change to IP to generate a zero ip_id field when DF is used only partly achieves its objectives for TCP, and is (arguably) a detriment to security/privacy. There is also a risk of TCP interoperation problems with some Windows95/2000 systems using VJ header compression from this change. This change seems to have taken place after release 5.1, so is new to 5.2 RC1 and RC2. TCP emits FIN-ACK without DF, so now just one segment per TCP connection goes out with a non-zero ip_id. This means the change's objectives are not really met for TCP; it just means FIN-ACK must be observed. Worse, for many systems the ip_id now becomes a close approximate count of the number of TCP connections it has made, so external observers can fairly easily count the number of TCP connections a system makes, which was not possible before this change. To me this seems more of a privacy issue for all FreeBSD users than the NAT-only issue in Steve Bellovin's paper this change seeks to solve. Another consideration is that Linux made exactly this change some time ago, around Linux 2.4.4, but was forced to backout the change because (I think) of practical connectivity issues related to the comment in include/net/ip.h ip_select_ident() where it now implements an incrementing ip_id for DF: /* This is only to work around buggy Windows95/2000 * VJ compression implementations. If the ID field * does not change, they drop every other packet in * a TCP stream using header compression. */ Has anyone checked that this buggy Windows95/2000 VJ compression problem is no longer an issue in practice? I doubt that the large web hosters who use FreeBSD would be best-pleased if they ran into this for even just a few users - especially as there is no config option to disable this change. I suggest this change is backed out of 5.2, to give more time for these issues to be considered and tested. NB I've read the source and I can't see why the FIN-ACK goes out without a DF, it's emitted as TCP moves from FIN_WAIT_x state to TIME_WAIT probably at line 3091 of tcp_input.c with a call to tcp_output(). tcp_output() always appears to set IP_DF at line 998 of tcp_output.c, if path_mtu_discovery is enabled. A puzzle. Here's tcpdump output from a HTTP HEAD request showing the issue, the last segment is the FIN-ACK with the only non-zero id (and no DF) from fbsd-5_2RC2.80: 17:10:26.566423 fbsd-4_3.3700 > fbsd-5_2RC2.80: S 3955049829:3955049829(0) win 16384 (DF) (ttl 64, id 36227) 17:10:26.604219 fbsd-5_2RC2.80 > fbsd-4_3.3700: S 2579960593:2579960593(0) ack 3955049830 win 65535 (DF) (ttl 53, id 0) 17:10:26.604259 fbsd-4_3.3700 > fbsd-5_2RC2.80: . ack 1 win 17280 (DF) (ttl 64, id 36228) 17:10:26.604426 fbsd-4_3.3700 > fbsd-5_2RC2.80: P 1:61(60) ack 1 win 17280 (DF) (ttl 64, id 36229) 17:10:26.655004 fbsd-5_2RC2.80 > fbsd-4_3.3700: P 1:278(277) ack 61 win 33120 (DF) (ttl 53, id 0) 17:10:26.659403 fbsd-5_2RC2.80 > fbsd-4_3.3700: F 278:278(0) ack 61 win 33120 (DF) (ttl 53, id 0) 17:10:26.659430 fbsd-4_3.3700 > fbsd-5_2RC2.80: . ack 279 win 17280 (DF) (ttl 64, id 36231) 17:10:26.659468 fbsd-4_3.3700 > fbsd-5_2RC2.80: F 61:61(0) ack 279 win 17280 (DF) (ttl 64, id 36232) 17:10:26.694533 fbsd-5_2RC2.80 > fbsd-4_3.3700: . ack 62 win 33119 (ttl 53, id 25945) Note that with this change ip_id is no longer in network byte order, so id appears to increase in steps of 256 from i386 systems; you need to be aware of this if you are using this to count TCP connections. Incidentally this is also a new information leak from this change, you can remotely identify the endian-ness of FreeBSD systems, in practice currently if it runs on i386; whether this really matters for security is debatable. Thanks to Boris Staeblow and Tim Rylance for highlighting this change and helping me diagnose the issues. >How-To-Repeat: Make TCP connections to a 5.2-RC2 system. Use tcpdump to see the issue, observe the final FIN-ACK of a connection. >Fix: Back out the src/sys/netinet/ip_output.c Revision 1.189 change: wollman 2003/05/31 10:55:21 PDT FreeBSD src repository Modified files: sys/netinet ip_output.c Log: Don't generate an ip_id for packets with the DF bit set; ip_id is only meaningful for fragments. Also don't bother to byte-swap the ip_id when we do generate it; it is only used at the receiver as a nonce. I tried several different permutations of this code with no measurable difference to each other or to the unmodified version, so I've settled on the one for which gcc seems to generate the best code. (If anyone cares to microoptimize this differently for an architecture where it actually matters, feel free.) Suggested by: Steve Bellovin's paper in IMW'02 Revision Changes Path 1.189 +17 -4 src/sys/netinet/ip_output.c >Release-Note: >Audit-Trail: >Unformatted: