From 74f471aa5cf5bd53bce113fed3d0f77b5dbb534b Mon Sep 17 00:00:00 2001 From: rpaulo Date: Tue, 4 Mar 2008 19:16:21 +0000 Subject: Change the default port range for outgoing connections by introducing IPPORT_EPHEMERALFIRST and IPPORT_EPHEMERALLAST with values 10000 and 65535 respectively. The rationale behind is that it makes the attacker's life more difficult if he/she wants to guess the ephemeral port range and also lowers the probability of a port colision (described in draft-ietf-tsvwg-port-randomization-01.txt). While there, remove code duplication in in_pcbbind_setup(). Submitted by: Fernando Gont Approved by: njl (mentor) Reviewed by: silby, bms Discussed on: freebsd-net --- sys/netinet/in.h | 12 +++++++---- sys/netinet/in_pcb.c | 61 ++++++++++++++++++---------------------------------- 2 files changed, 29 insertions(+), 44 deletions(-) (limited to 'sys') diff --git a/sys/netinet/in.h b/sys/netinet/in.h index 1fca43d..c470dc4 100644 --- a/sys/netinet/in.h +++ b/sys/netinet/in.h @@ -293,8 +293,7 @@ __END_DECLS * * 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 @@ __END_DECLS #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 10000 +#define IPPORT_EPHEMERALLAST 65535 + +/* + * Dynamic port range, used by IP_PORTRANGE_HIGH. */ #define IPPORT_HIFIRSTAUTO 49152 #define IPPORT_HILASTAUTO 65535 diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c index 1ddc020..768a947 100644 --- a/sys/netinet/in_pcb.c +++ b/sys/netinet/in_pcb.c @@ -89,8 +89,8 @@ __FBSDID("$FreeBSD$"); */ 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; /* 10000 */ +int ipport_lastauto = IPPORT_EPHEMERALLAST; /* 65535 */ int ipport_hifirstauto = IPPORT_HIFIRSTAUTO; /* 49152 */ int ipport_hilastauto = IPPORT_HILASTAUTO; /* 65535 */ @@ -393,7 +393,7 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, 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 @@ in_pcbbind_setup(struct inpcb *inp, struct sockaddr *nam, in_addr_t *laddrp, /* * 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); -- cgit v1.1