diff options
author | Eric Dumazet <eric.dumazet@gmail.com> | 2010-03-08 14:32:01 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@suse.de> | 2010-04-01 19:02:11 -0400 |
commit | e3f1272e2083ee9cf0a21a405ff24b95c2423a97 (patch) | |
tree | 38d2819c02772c41dd56510ca3b66975bf8e27eb /net | |
parent | f1783b77374b69b6b91123da581e939caa13b7d1 (diff) |
tcp: Fix tcp_make_synack()
[ Upstream commit 28b2774a0d5852236dab77a4147b8b88548110f1 ]
Commit 4957faad (TCPCT part 1g: Responder Cookie => Initiator), part
of TCP_COOKIE_TRANSACTION implementation, forgot to correctly size
synack skb in case user data must be included.
Many thanks to Mika Pentillä for spotting this error.
Reported-by: Penttillä Mika <mika.penttila@ixonos.com>
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_output.c | 18 |
1 files changed, 9 insertions, 9 deletions
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c index 383ce237640f..dc26654cf119 100644 --- a/net/ipv4/tcp_output.c +++ b/net/ipv4/tcp_output.c | |||
@@ -2393,13 +2393,17 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2393 | struct tcp_extend_values *xvp = tcp_xv(rvp); | 2393 | struct tcp_extend_values *xvp = tcp_xv(rvp); |
2394 | struct inet_request_sock *ireq = inet_rsk(req); | 2394 | struct inet_request_sock *ireq = inet_rsk(req); |
2395 | struct tcp_sock *tp = tcp_sk(sk); | 2395 | struct tcp_sock *tp = tcp_sk(sk); |
2396 | const struct tcp_cookie_values *cvp = tp->cookie_values; | ||
2396 | struct tcphdr *th; | 2397 | struct tcphdr *th; |
2397 | struct sk_buff *skb; | 2398 | struct sk_buff *skb; |
2398 | struct tcp_md5sig_key *md5; | 2399 | struct tcp_md5sig_key *md5; |
2399 | int tcp_header_size; | 2400 | int tcp_header_size; |
2400 | int mss; | 2401 | int mss; |
2402 | int s_data_desired = 0; | ||
2401 | 2403 | ||
2402 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15, 1, GFP_ATOMIC); | 2404 | if (cvp != NULL && cvp->s_data_constant && cvp->s_data_desired) |
2405 | s_data_desired = cvp->s_data_desired; | ||
2406 | skb = sock_wmalloc(sk, MAX_TCP_HEADER + 15 + s_data_desired, 1, GFP_ATOMIC); | ||
2403 | if (skb == NULL) | 2407 | if (skb == NULL) |
2404 | return NULL; | 2408 | return NULL; |
2405 | 2409 | ||
@@ -2454,16 +2458,12 @@ struct sk_buff *tcp_make_synack(struct sock *sk, struct dst_entry *dst, | |||
2454 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); | 2458 | TCPCB_FLAG_SYN | TCPCB_FLAG_ACK); |
2455 | 2459 | ||
2456 | if (OPTION_COOKIE_EXTENSION & opts.options) { | 2460 | if (OPTION_COOKIE_EXTENSION & opts.options) { |
2457 | const struct tcp_cookie_values *cvp = tp->cookie_values; | 2461 | if (s_data_desired) { |
2458 | 2462 | u8 *buf = skb_put(skb, s_data_desired); | |
2459 | if (cvp != NULL && | ||
2460 | cvp->s_data_constant && | ||
2461 | cvp->s_data_desired > 0) { | ||
2462 | u8 *buf = skb_put(skb, cvp->s_data_desired); | ||
2463 | 2463 | ||
2464 | /* copy data directly from the listening socket. */ | 2464 | /* copy data directly from the listening socket. */ |
2465 | memcpy(buf, cvp->s_data_payload, cvp->s_data_desired); | 2465 | memcpy(buf, cvp->s_data_payload, s_data_desired); |
2466 | TCP_SKB_CB(skb)->end_seq += cvp->s_data_desired; | 2466 | TCP_SKB_CB(skb)->end_seq += s_data_desired; |
2467 | } | 2467 | } |
2468 | 2468 | ||
2469 | if (opts.hash_size > 0) { | 2469 | if (opts.hash_size > 0) { |