aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorFlorian Westphal <fw@strlen.de>2010-06-16 17:42:15 -0400
committerDavid S. Miller <davem@davemloft.net>2010-06-16 17:42:15 -0400
commit8c76368174ed2359739f1b7b8a9c042b1ef839c4 (patch)
tree143aa28c9438b24154bc3d1e36b432a534eca50c /net/ipv4
parent317fe0e6c5dc9448bcef41a2e31fecfd3dba7f55 (diff)
syncookies: check decoded options against sysctl settings
Discard the ACK if we find options that do not match current sysctl settings. Previously it was possible to create a connection with sack, wscale, etc. enabled even if the feature was disabled via sysctl. Also remove an unneeded call to tcp_sack_reset() in cookie_check_timestamp: Both call sites (cookie_v4_check, cookie_v6_check) zero "struct tcp_options_received", hand it to tcp_parse_options() (which does not change tcp_opt->num_sacks/dsack) and then call cookie_check_timestamp(). Even if num_sacks/dsacks were changed, the structure is allocated on the stack and after cookie_check_timestamp returns only a few selected members are copied to the inet_request_sock. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/syncookies.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/net/ipv4/syncookies.c b/net/ipv4/syncookies.c
index 02bef6aa8b30..51b5662545d6 100644
--- a/net/ipv4/syncookies.c
+++ b/net/ipv4/syncookies.c
@@ -230,23 +230,36 @@ static inline struct sock *get_cookie_sock(struct sock *sk, struct sk_buff *skb,
230 * The lowest 4 bits are for snd_wscale 230 * The lowest 4 bits are for snd_wscale
231 * The next 4 lsb are for rcv_wscale 231 * The next 4 lsb are for rcv_wscale
232 * The next lsb is for sack_ok 232 * The next lsb is for sack_ok
233 *
234 * return false if we decode an option that should not be.
233 */ 235 */
234void cookie_check_timestamp(struct tcp_options_received *tcp_opt) 236bool cookie_check_timestamp(struct tcp_options_received *tcp_opt)
235{ 237{
236 /* echoed timestamp, 9 lowest bits contain options */ 238 /* echoed timestamp, 9 lowest bits contain options */
237 u32 options = tcp_opt->rcv_tsecr & TSMASK; 239 u32 options = tcp_opt->rcv_tsecr & TSMASK;
238 240
241 if (!tcp_opt->saw_tstamp) {
242 tcp_clear_options(tcp_opt);
243 return true;
244 }
245
246 if (!sysctl_tcp_timestamps)
247 return false;
248
239 tcp_opt->snd_wscale = options & 0xf; 249 tcp_opt->snd_wscale = options & 0xf;
240 options >>= 4; 250 options >>= 4;
241 tcp_opt->rcv_wscale = options & 0xf; 251 tcp_opt->rcv_wscale = options & 0xf;
242 252
243 tcp_opt->sack_ok = (options >> 4) & 0x1; 253 tcp_opt->sack_ok = (options >> 4) & 0x1;
244 254
245 if (tcp_opt->sack_ok) 255 if (tcp_opt->sack_ok && !sysctl_tcp_sack)
246 tcp_sack_reset(tcp_opt); 256 return false;
247 257
248 if (tcp_opt->snd_wscale || tcp_opt->rcv_wscale) 258 if (tcp_opt->snd_wscale || tcp_opt->rcv_wscale) {
249 tcp_opt->wscale_ok = 1; 259 tcp_opt->wscale_ok = 1;
260 return sysctl_tcp_window_scaling != 0;
261 }
262 return true;
250} 263}
251EXPORT_SYMBOL(cookie_check_timestamp); 264EXPORT_SYMBOL(cookie_check_timestamp);
252 265
@@ -281,8 +294,8 @@ struct sock *cookie_v4_check(struct sock *sk, struct sk_buff *skb,
281 memset(&tcp_opt, 0, sizeof(tcp_opt)); 294 memset(&tcp_opt, 0, sizeof(tcp_opt));
282 tcp_parse_options(skb, &tcp_opt, &hash_location, 0); 295 tcp_parse_options(skb, &tcp_opt, &hash_location, 0);
283 296
284 if (tcp_opt.saw_tstamp) 297 if (!cookie_check_timestamp(&tcp_opt))
285 cookie_check_timestamp(&tcp_opt); 298 goto out;
286 299
287 ret = NULL; 300 ret = NULL;
288 req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */ 301 req = inet_reqsk_alloc(&tcp_request_sock_ops); /* for safety */