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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.