diff options
author | Florian Westphal <fw@strlen.de> | 2013-09-20 16:32:55 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-09-24 10:39:58 -0400 |
commit | 8c27bd75f04fb9cb70c69c3cfe24f4e6d8e15906 (patch) | |
tree | 28156d5d01cd4393da57eb328db87d784bdd4260 /net/ipv6/syncookies.c | |
parent | 61f860c356c3d15b6cf48ef35beea664921dec1e (diff) |
tcp: syncookies: reduce cookie lifetime to 128 seconds
We currently accept cookies that were created less than 4 minutes ago
(ie, cookies with counter delta 0-3). Combined with the 8 mss table
values, this yields 32 possible values (out of 2**32) that will be valid.
Reducing the lifetime to < 2 minutes halves the guessing chance while
still providing a large enough period.
While at it, get rid of jiffies value -- they overflow too quickly on
32 bit platforms.
getnstimeofday is used to create a counter that increments every 64s.
perf shows getnstimeofday cost is negible compared to sha_transform;
normal tcp initial sequence number generation uses getnstimeofday, too.
Reported-by: Jakob Lell <jakob@jakoblell.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv6/syncookies.c')
-rw-r--r-- | net/ipv6/syncookies.c | 24 |
1 files changed, 7 insertions, 17 deletions
diff --git a/net/ipv6/syncookies.c b/net/ipv6/syncookies.c index bf63ac8a49b9..13ca0a0ea680 100644 --- a/net/ipv6/syncookies.c +++ b/net/ipv6/syncookies.c | |||
@@ -36,14 +36,6 @@ static __u16 const msstab[] = { | |||
36 | 9000 - 60, | 36 | 9000 - 60, |
37 | }; | 37 | }; |
38 | 38 | ||
39 | /* | ||
40 | * This (misnamed) value is the age of syncookie which is permitted. | ||
41 | * Its ideal value should be dependent on TCP_TIMEOUT_INIT and | ||
42 | * sysctl_tcp_retries1. It's a rather complicated formula (exponential | ||
43 | * backoff) to compute at runtime so it's currently hardcoded here. | ||
44 | */ | ||
45 | #define COUNTER_TRIES 4 | ||
46 | |||
47 | static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, | 39 | static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb, |
48 | struct request_sock *req, | 40 | struct request_sock *req, |
49 | struct dst_entry *dst) | 41 | struct dst_entry *dst) |
@@ -86,8 +78,9 @@ static u32 cookie_hash(const struct in6_addr *saddr, const struct in6_addr *dadd | |||
86 | static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr, | 78 | static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr, |
87 | const struct in6_addr *daddr, | 79 | const struct in6_addr *daddr, |
88 | __be16 sport, __be16 dport, __u32 sseq, | 80 | __be16 sport, __be16 dport, __u32 sseq, |
89 | __u32 count, __u32 data) | 81 | __u32 data) |
90 | { | 82 | { |
83 | u32 count = tcp_cookie_time(); | ||
91 | return (cookie_hash(saddr, daddr, sport, dport, 0, 0) + | 84 | return (cookie_hash(saddr, daddr, sport, dport, 0, 0) + |
92 | sseq + (count << COOKIEBITS) + | 85 | sseq + (count << COOKIEBITS) + |
93 | ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data) | 86 | ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data) |
@@ -96,15 +89,14 @@ static __u32 secure_tcp_syn_cookie(const struct in6_addr *saddr, | |||
96 | 89 | ||
97 | static __u32 check_tcp_syn_cookie(__u32 cookie, const struct in6_addr *saddr, | 90 | static __u32 check_tcp_syn_cookie(__u32 cookie, const struct in6_addr *saddr, |
98 | const struct in6_addr *daddr, __be16 sport, | 91 | const struct in6_addr *daddr, __be16 sport, |
99 | __be16 dport, __u32 sseq, __u32 count, | 92 | __be16 dport, __u32 sseq) |
100 | __u32 maxdiff) | ||
101 | { | 93 | { |
102 | __u32 diff; | 94 | __u32 diff, count = tcp_cookie_time(); |
103 | 95 | ||
104 | cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq; | 96 | cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq; |
105 | 97 | ||
106 | diff = (count - (cookie >> COOKIEBITS)) & ((__u32) -1 >> COOKIEBITS); | 98 | diff = (count - (cookie >> COOKIEBITS)) & ((__u32) -1 >> COOKIEBITS); |
107 | if (diff >= maxdiff) | 99 | if (diff >= MAX_SYNCOOKIE_AGE) |
108 | return (__u32)-1; | 100 | return (__u32)-1; |
109 | 101 | ||
110 | return (cookie - | 102 | return (cookie - |
@@ -125,8 +117,7 @@ u32 __cookie_v6_init_sequence(const struct ipv6hdr *iph, | |||
125 | *mssp = msstab[mssind]; | 117 | *mssp = msstab[mssind]; |
126 | 118 | ||
127 | return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source, | 119 | return secure_tcp_syn_cookie(&iph->saddr, &iph->daddr, th->source, |
128 | th->dest, ntohl(th->seq), | 120 | th->dest, ntohl(th->seq), mssind); |
129 | jiffies / (HZ * 60), mssind); | ||
130 | } | 121 | } |
131 | EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); | 122 | EXPORT_SYMBOL_GPL(__cookie_v6_init_sequence); |
132 | 123 | ||
@@ -146,8 +137,7 @@ int __cookie_v6_check(const struct ipv6hdr *iph, const struct tcphdr *th, | |||
146 | { | 137 | { |
147 | __u32 seq = ntohl(th->seq) - 1; | 138 | __u32 seq = ntohl(th->seq) - 1; |
148 | __u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr, | 139 | __u32 mssind = check_tcp_syn_cookie(cookie, &iph->saddr, &iph->daddr, |
149 | th->source, th->dest, seq, | 140 | th->source, th->dest, seq); |
150 | jiffies / (HZ * 60), COUNTER_TRIES); | ||
151 | 141 | ||
152 | return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0; | 142 | return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0; |
153 | } | 143 | } |