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/ipv4/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/ipv4/syncookies.c')
-rw-r--r-- | net/ipv4/syncookies.c | 31 |
1 files changed, 10 insertions, 21 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c index 14a15c49129d..b6ea2979a2b7 100644 --- a/net/ipv4/syncookies.c +++ b/net/ipv4/syncookies.c | |||
@@ -89,8 +89,7 @@ __u32 cookie_init_timestamp(struct request_sock *req) | |||
89 | 89 | ||
90 | 90 | ||
91 | static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport, | 91 | static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport, |
92 | __be16 dport, __u32 sseq, __u32 count, | 92 | __be16 dport, __u32 sseq, __u32 data) |
93 | __u32 data) | ||
94 | { | 93 | { |
95 | /* | 94 | /* |
96 | * Compute the secure sequence number. | 95 | * Compute the secure sequence number. |
@@ -102,7 +101,7 @@ static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport, | |||
102 | * As an extra hack, we add a small "data" value that encodes the | 101 | * As an extra hack, we add a small "data" value that encodes the |
103 | * MSS into the second hash value. | 102 | * MSS into the second hash value. |
104 | */ | 103 | */ |
105 | 104 | u32 count = tcp_cookie_time(); | |
106 | return (cookie_hash(saddr, daddr, sport, dport, 0, 0) + | 105 | return (cookie_hash(saddr, daddr, sport, dport, 0, 0) + |
107 | sseq + (count << COOKIEBITS) + | 106 | sseq + (count << COOKIEBITS) + |
108 | ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data) | 107 | ((cookie_hash(saddr, daddr, sport, dport, count, 1) + data) |
@@ -114,22 +113,21 @@ static __u32 secure_tcp_syn_cookie(__be32 saddr, __be32 daddr, __be16 sport, | |||
114 | * If the syncookie is bad, the data returned will be out of | 113 | * If the syncookie is bad, the data returned will be out of |
115 | * range. This must be checked by the caller. | 114 | * range. This must be checked by the caller. |
116 | * | 115 | * |
117 | * The count value used to generate the cookie must be within | 116 | * The count value used to generate the cookie must be less than |
118 | * "maxdiff" if the current (passed-in) "count". The return value | 117 | * MAX_SYNCOOKIE_AGE minutes in the past. |
119 | * is (__u32)-1 if this test fails. | 118 | * The return value (__u32)-1 if this test fails. |
120 | */ | 119 | */ |
121 | static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr, | 120 | static __u32 check_tcp_syn_cookie(__u32 cookie, __be32 saddr, __be32 daddr, |
122 | __be16 sport, __be16 dport, __u32 sseq, | 121 | __be16 sport, __be16 dport, __u32 sseq) |
123 | __u32 count, __u32 maxdiff) | ||
124 | { | 122 | { |
125 | __u32 diff; | 123 | u32 diff, count = tcp_cookie_time(); |
126 | 124 | ||
127 | /* Strip away the layers from the cookie */ | 125 | /* Strip away the layers from the cookie */ |
128 | cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq; | 126 | cookie -= cookie_hash(saddr, daddr, sport, dport, 0, 0) + sseq; |
129 | 127 | ||
130 | /* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */ | 128 | /* Cookie is now reduced to (count * 2^24) ^ (hash % 2^24) */ |
131 | diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS); | 129 | diff = (count - (cookie >> COOKIEBITS)) & ((__u32) - 1 >> COOKIEBITS); |
132 | if (diff >= maxdiff) | 130 | if (diff >= MAX_SYNCOOKIE_AGE) |
133 | return (__u32)-1; | 131 | return (__u32)-1; |
134 | 132 | ||
135 | return (cookie - | 133 | return (cookie - |
@@ -173,7 +171,7 @@ u32 __cookie_v4_init_sequence(const struct iphdr *iph, const struct tcphdr *th, | |||
173 | 171 | ||
174 | return secure_tcp_syn_cookie(iph->saddr, iph->daddr, | 172 | return secure_tcp_syn_cookie(iph->saddr, iph->daddr, |
175 | th->source, th->dest, ntohl(th->seq), | 173 | th->source, th->dest, ntohl(th->seq), |
176 | jiffies / (HZ * 60), mssind); | 174 | mssind); |
177 | } | 175 | } |
178 | EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); | 176 | EXPORT_SYMBOL_GPL(__cookie_v4_init_sequence); |
179 | 177 | ||
@@ -189,13 +187,6 @@ __u32 cookie_v4_init_sequence(struct sock *sk, struct sk_buff *skb, __u16 *mssp) | |||
189 | } | 187 | } |
190 | 188 | ||
191 | /* | 189 | /* |
192 | * This (misnamed) value is the age of syncookie which is permitted. | ||
193 | * Its ideal value should be dependent on TCP_TIMEOUT_INIT and | ||
194 | * sysctl_tcp_retries1. It's a rather complicated formula (exponential | ||
195 | * backoff) to compute at runtime so it's currently hardcoded here. | ||
196 | */ | ||
197 | #define COUNTER_TRIES 4 | ||
198 | /* | ||
199 | * Check if a ack sequence number is a valid syncookie. | 190 | * Check if a ack sequence number is a valid syncookie. |
200 | * Return the decoded mss if it is, or 0 if not. | 191 | * Return the decoded mss if it is, or 0 if not. |
201 | */ | 192 | */ |
@@ -204,9 +195,7 @@ int __cookie_v4_check(const struct iphdr *iph, const struct tcphdr *th, | |||
204 | { | 195 | { |
205 | __u32 seq = ntohl(th->seq) - 1; | 196 | __u32 seq = ntohl(th->seq) - 1; |
206 | __u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr, | 197 | __u32 mssind = check_tcp_syn_cookie(cookie, iph->saddr, iph->daddr, |
207 | th->source, th->dest, seq, | 198 | th->source, th->dest, seq); |
208 | jiffies / (HZ * 60), | ||
209 | COUNTER_TRIES); | ||
210 | 199 | ||
211 | return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0; | 200 | return mssind < ARRAY_SIZE(msstab) ? msstab[mssind] : 0; |
212 | } | 201 | } |