From: Michael Vittrup Larsen <michael.vittrup.larsen@ericsson.com>
To: Stephen Hemminger <shemminger@osdl.org>
Cc: "David S. Miller" <davem@davemloft.net>, netdev@oss.sgi.com
Subject: Re: [PATCH] tcp: efficient port randomisation (revised)
Date: Fri, 19 Nov 2004 08:38:37 +0100 [thread overview]
Message-ID: <200411190838.37802.michael.vittrup.larsen@ericsson.com> (raw)
In-Reply-To: <20041117153025.160eaa04@zqx3.pdx.osdl.net>
I have looked through this patch and found no problems - thank you for
implementing the draft.
/Michael
On Thursday 18 November 2004 00:30, Stephen Hemminger wrote:
> Here is a more conservative version of earlier patch vthat keeps the same
> port rover locking and global port rover. This randomizes TCP ephemeral
> ports of incoming connections using variation of existing sequence number
> hash.
>
> Thanks to original author Michael Larsen.
> http://www.ietf.org/internet-drafts/draft-larsen-tsvwg-port-randomisation-0
>0.txt
>
> It behaves correctly if someone is perverse and sets low > high
> and it separates the outgoing port rover (tcp_port_rover) from the incoming
> port rover (start_rover).
>
> Signed-off-by: Stephen Hemminger <shemminger@osdl.org>
>
> diff -Nru a/drivers/char/random.c b/drivers/char/random.c
> --- a/drivers/char/random.c 2004-11-17 15:21:43 -08:00
> +++ b/drivers/char/random.c 2004-11-17 15:21:43 -08:00
> @@ -2347,6 +2347,24 @@
> return halfMD4Transform(hash, keyptr->secret);
> }
>
> +/* Generate secure starting point for ephemeral TCP port search */
> +u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16 dport)
> +{
> + struct keydata *keyptr = get_keyptr();
> + u32 hash[4];
> +
> + /*
> + * Pick a unique starting offset for each ephemeral port search
> + * (saddr, daddr, dport) and 48bits of random data.
> + */
> + hash[0] = saddr;
> + hash[1] = daddr;
> + hash[2] = dport ^ keyptr->secret[10];
> + hash[3] = keyptr->secret[11];
> +
> + return halfMD4Transform(hash, keyptr->secret);
> +}
> +
> #ifdef CONFIG_SYN_COOKIES
> /*
> * Secure SYN cookie computation. This is the algorithm worked out by
> diff -Nru a/include/linux/random.h b/include/linux/random.h
> --- a/include/linux/random.h 2004-11-17 15:21:43 -08:00
> +++ b/include/linux/random.h 2004-11-17 15:21:43 -08:00
> @@ -52,6 +52,7 @@
> void generate_random_uuid(unsigned char uuid_out[16]);
>
> extern __u32 secure_ip_id(__u32 daddr);
> +extern u32 secure_tcp_port_ephemeral(__u32 saddr, __u32 daddr, __u16
> dport); extern __u32 secure_tcp_sequence_number(__u32 saddr, __u32 daddr,
> __u16 sport, __u16 dport);
> extern __u32 secure_tcp_syn_cookie(__u32 saddr, __u32 daddr,
> diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
> --- a/net/ipv4/tcp_ipv4.c 2004-11-17 15:21:43 -08:00
> +++ b/net/ipv4/tcp_ipv4.c 2004-11-17 15:21:43 -08:00
> @@ -636,6 +636,13 @@
> return -EADDRNOTAVAIL;
> }
>
> +static inline u32 connect_port_offset(const struct sock *sk)
> +{
> + const struct inet_opt *inet = inet_sk(sk);
> + return secure_tcp_port_ephemeral(inet->rcv_saddr, inet->daddr,
> + inet->dport);
> +}
> +
> /*
> * Bind a port for a connect operation and hash it.
> */
> @@ -647,10 +654,12 @@
> int ret;
>
> if (!snum) {
> - int rover;
> - int low = sysctl_local_port_range[0];
> - int high = sysctl_local_port_range[1];
> - int remaining = (high - low) + 1;
> + const u16 low = sysctl_local_port_range[0];
> + const u16 high = sysctl_local_port_range[1];
> + u16 rover = low;
> + int remaining = (high-low) + 1;
> + u32 offset = connect_port_offset(sk);
> + static u32 rover_start;
> struct hlist_node *node;
> struct tcp_tw_bucket *tw = NULL;
>
> @@ -660,7 +669,7 @@
> * tcp_portalloc_lock before next submission to Linus.
> * As soon as we touch this place at all it is time to think.
> *
> - * Now it protects single _advisory_ variable tcp_port_rover,
> + * Now it protects single _advisory_ variable rover_start,
> * hence it is mostly useless.
> * Code will work nicely if we just delete it, but
> * I am afraid in contented case it will work not better or
> @@ -670,12 +679,9 @@
> * memory pingpong. Any ideas how to do this in a nice way?
> */
> spin_lock(&tcp_portalloc_lock);
> - rover = tcp_port_rover;
> -
> - do {
> - rover++;
> - if ((rover < low) || (rover > high))
> - rover = low;
> + while (remaining > 0) {
> + rover = low + (rover_start + offset) %
> + (high - low);
> head = &tcp_bhash[tcp_bhashfn(rover)];
> spin_lock(&head->lock);
>
> @@ -706,8 +712,9 @@
>
> next_port:
> spin_unlock(&head->lock);
> - } while (--remaining > 0);
> - tcp_port_rover = rover;
> + --remaining;
> + ++rover_start;
> + }
> spin_unlock(&tcp_portalloc_lock);
>
> local_bh_enable();
> @@ -716,7 +723,6 @@
>
> ok:
> /* All locks still held and bhs disabled */
> - tcp_port_rover = rover;
> spin_unlock(&tcp_portalloc_lock);
>
> tcp_bind_hash(sk, tb, rover);
next prev parent reply other threads:[~2004-11-19 7:38 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20041027092531.78fe438c@guest-251-240.pdx.osdl.net>
[not found] ` <200410291048.01955.michael.vittrup.larsen@ericsson.com>
2004-10-29 17:28 ` [PATCH] tcp: efficient port randomisation Stephen Hemminger
2004-11-01 9:58 ` Michael Vittrup Larsen
2004-11-01 17:20 ` Stephen Hemminger
2004-11-02 7:54 ` Michael Vittrup Larsen
2004-11-04 18:01 ` Stephen Hemminger
2004-11-05 10:03 ` Michael Vittrup Larsen
2004-11-17 23:30 ` [PATCH] tcp: efficient port randomisation (revised) Stephen Hemminger
2004-11-19 7:38 ` Michael Vittrup Larsen [this message]
2004-12-01 5:46 ` David S. Miller
[not found] ` <20041201152446.3a0d5ce3@dxpl.pdx.osdl.net>
[not found] ` <20041201204622.7b760400.davem@davemloft.net>
2004-12-02 21:49 ` Stephen Hemminger
2004-12-02 21:52 ` David S. Miller
2004-12-02 22:51 ` Stephen Hemminger
2004-12-02 23:01 ` Stephen Hemminger
2004-12-04 5:42 ` Stephen Hemminger
2004-12-06 8:18 ` Michael Vittrup Larsen
2004-12-06 17:42 ` [PATCH] tcp: efficient port randomisation (rev 3) Stephen Hemminger
2004-12-09 7:55 ` David S. Miller
2004-12-11 1:09 ` [PATCH] tcp: efficient port randomistion " Stephen Hemminger
2004-12-20 23:39 ` David S. Miller
2005-06-22 9:17 ` Michael Vittrup Larsen
2005-06-22 16:44 ` Stephen Hemminger
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=200411190838.37802.michael.vittrup.larsen@ericsson.com \
--to=michael.vittrup.larsen@ericsson.com \
--cc=davem@davemloft.net \
--cc=netdev@oss.sgi.com \
--cc=shemminger@osdl.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).