From owner-freebsd-net@FreeBSD.ORG Sat Mar 1 13:39:16 2008 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A04E91065670 for ; Sat, 1 Mar 2008 13:39:16 +0000 (UTC) (envelope-from fernando@gont.com.ar) Received: from smtp1.xmundo.net (smtp1.xmundo.net [201.216.232.80]) by mx1.freebsd.org (Postfix) with ESMTP id 120B38FC18 for ; Sat, 1 Mar 2008 13:39:15 +0000 (UTC) (envelope-from fernando@gont.com.ar) Received: from venus.xmundo.net (venus.xmundo.net [201.216.232.56]) by smtp1.xmundo.net (Postfix) with ESMTP id 41A845A8A73; Sat, 1 Mar 2008 11:39:15 -0200 (ARDT) Received: from notebook.gont.com.ar (201-254-62-65.speedy.com.ar [201.254.62.65] (may be forged)) (authenticated bits=0) by venus.xmundo.net (8.13.8/8.13.8) with ESMTP id m21DcY9Z026418; Sat, 1 Mar 2008 11:38:53 -0200 Message-Id: <200803011338.m21DcY9Z026418@venus.xmundo.net> X-Mailer: QUALCOMM Windows Eudora Version 7.1.0.9 Date: Sat, 01 Mar 2008 11:34:27 -0200 To: freebsd-net@freebsd.org From: Fernando Gont Mime-Version: 1.0 Content-Type: text/plain; charset="us-ascii"; format=flowed X-Greylist: Sender succeeded SMTP AUTH authentication, not delayed by milter-greylist-3.0 (venus.xmundo.net [201.216.232.56]); Sat, 01 Mar 2008 11:39:12 -0200 (ARDT) Cc: Rui Paulo Subject: Ephemeral port range (patch) X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 01 Mar 2008 13:39:16 -0000 Folks, This patch changes the default ephemeral port range from 49152-65535 to 1024-65535. This makes it harder for an attacker to guess the ephemeral ports (as the port number space is larger). Also, it makes the chances of port number collisions smaller. (http://www.ietf.org/internet-drafts/draft-ietf-tsvwg-port-randomization-01.txt) This patch also includes my previous patch that eliminated duplicated code in in_pcb_bind(). Index: in.h =================================================================== RCS file: /home/ncvs/src/sys/netinet/in.h,v retrieving revision 1.100 diff -u -r1.100 in.h --- in.h 12 Jun 2007 16:24:53 -0000 1.100 +++ in.h 1 Mar 2008 09:00:10 -0000 @@ -293,8 +293,7 @@ * * The value IP_PORTRANGE_HIGH changes the range of candidate port numbers * into the "high" range. These are reserved for client outbound connections - * which do not want to be filtered by any firewalls. Note that by default - * this is the same as IP_PORTRANGE_DEFAULT. + * which do not want to be filtered by any firewalls. * * The value IP_PORTRANGE_LOW changes the range to the "low" are * that is (by convention) restricted to privileged processes. This @@ -331,8 +330,13 @@ #define IPPORT_RESERVED 1024 /* - * Default local port range, used by both IP_PORTRANGE_DEFAULT - * and IP_PORTRANGE_HIGH. + * Default local port range, used by IP_PORTRANGE_DEFAULT + */ +#define IPPORT_EPHEMERALFIRST 1024 +#define IPPORT_EPHEMERALLAST 65535 + +/* + * Dynamic port range, used by IP_PORTRANGE_HIGH. */ #define IPPORT_HIFIRSTAUTO 49152 #define IPPORT_HILASTAUTO 65535 Index: in_pcb.c =================================================================== RCS file: /home/ncvs/src/sys/netinet/in_pcb.c,v retrieving revision 1.198 diff -u -r1.198 in_pcb.c --- in_pcb.c 22 Dec 2007 10:06:11 -0000 1.198 +++ in_pcb.c 1 Mar 2008 09:00:11 -0000 @@ -89,8 +89,8 @@ */ int ipport_lowfirstauto = IPPORT_RESERVED - 1; /* 1023 */ int ipport_lowlastauto = IPPORT_RESERVEDSTART; /* 600 */ -int ipport_firstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ -int ipport_lastauto = IPPORT_HILASTAUTO; /* 65535 */ +int ipport_firstauto = IPPORT_EPHEMERALFIRST; /* 1024 */ +int ipport_lastauto = IPPORT_EPHEMERALLAST; /* 65535 */ int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ @@ -393,7 +393,7 @@ if (*lportp != 0) lport = *lportp; if (lport == 0) { - u_short first, last; + u_short first, last, aux; int count; if (laddr.s_addr != INADDR_ANY) @@ -440,47 +440,28 @@ /* * Simple check to ensure all ports are not used up causing * a deadlock here. - * - * We split the two cases (up and down) so that the direction - * is not being tested on each round of the loop. */ if (first > last) { - /* - * counting down - */ - if (dorandom) - *lastport = first - - (arc4random() % (first - last)); - count = first - last; + aux = first; + first = last; + last = aux; + } - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - --*lastport; - if (*lastport > first || *lastport < last) - *lastport = first; - lport = htons(*lastport); - } while (in_pcblookup_local(pcbinfo, laddr, lport, - wild)); - } else { - /* - * counting up - */ - if (dorandom) - *lastport = first + - (arc4random() % (last - first)); - count = last - first; + if (dorandom) + *lastport = first + + (arc4random() % (last - first)); - do { - if (count-- < 0) /* completely used? */ - return (EADDRNOTAVAIL); - ++*lastport; - if (*lastport < first || *lastport > last) - *lastport = first; - lport = htons(*lastport); - } while (in_pcblookup_local(pcbinfo, laddr, lport, - wild)); - } + count = last - first; + + do { + if (count-- < 0) /* completely used? */ + return (EADDRNOTAVAIL); + ++*lastport; + if (*lastport < first || *lastport > last) + *lastport = first; + lport = htons(*lastport); + } while (in_pcblookup_local(pcbinfo, laddr, lport, + wild)); } if (prison_ip(cred, 0, &laddr.s_addr)) return (EINVAL); Kind regards, -- Fernando Gont e-mail: fernando@gont.com.ar || fgont@acm.org PGP Fingerprint: 7809 84F5 322E 45C7 F1C9 3945 96EE A9EF D076 FFF1