From: Greg Kroah-Hartman Date: Wed, 9 Jan 2013 17:38:27 +0000 (-0800) Subject: 3.0-stable patches X-Git-Tag: v3.0.58~11 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=cfe28f3635c6b54df553775b4c91762de9aa5aea;p=thirdparty%2Fkernel%2Fstable-queue.git 3.0-stable patches added patches: net-sched-integer-overflow-fix.patch tcp-implement-rfc-5961-3.2.patch tcp-implement-rfc-5961-4.2.patch tcp-refine-syn-handling-in-tcp_validate_incoming.patch tcp-rfc-5961-5.2-blind-data-injection-attack-mitigation.patch tcp-tcp_replace_ts_recent-should-not-be-called-from-tcp_validate_incoming.patch --- diff --git a/queue-3.0/net-sched-integer-overflow-fix.patch b/queue-3.0/net-sched-integer-overflow-fix.patch new file mode 100644 index 00000000000..b779a784dca --- /dev/null +++ b/queue-3.0/net-sched-integer-overflow-fix.patch @@ -0,0 +1,31 @@ +From f1e20830f328777cee51eb181801d4838eda76fa Mon Sep 17 00:00:00 2001 +From: Stefan Hasko +Date: Fri, 21 Dec 2012 15:04:59 +0000 +Subject: net: sched: integer overflow fix + + +From: Stefan Hasko + +[ Upstream commit d2fe85da52e89b8012ffad010ef352a964725d5f ] + +Fixed integer overflow in function htb_dequeue + +Signed-off-by: Stefan Hasko +Acked-by: Eric Dumazet +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/sched/sch_htb.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/net/sched/sch_htb.c ++++ b/net/sched/sch_htb.c +@@ -876,7 +876,7 @@ ok: + q->now = psched_get_time(); + start_at = jiffies; + +- next_event = q->now + 5 * PSCHED_TICKS_PER_SEC; ++ next_event = q->now + 5LLU * PSCHED_TICKS_PER_SEC; + + for (level = 0; level < TC_HTB_MAXDEPTH; level++) { + /* common case optimization - skip event handler quickly */ diff --git a/queue-3.0/series b/queue-3.0/series index d6df1d413c6..bea7e191a14 100644 --- a/queue-3.0/series +++ b/queue-3.0/series @@ -28,3 +28,9 @@ cgroup-remove-incorrect-dget-dput-pair-in-cgroup_create_dir.patch x86-amd-disable-way-access-filter-on-piledriver-cpus.patch ftrace-do-not-function-trace-inlined-functions.patch sparc-huge_ptep_set_-functions-need-to-call-set_huge_pte_at.patch +net-sched-integer-overflow-fix.patch +tcp-implement-rfc-5961-3.2.patch +tcp-implement-rfc-5961-4.2.patch +tcp-refine-syn-handling-in-tcp_validate_incoming.patch +tcp-tcp_replace_ts_recent-should-not-be-called-from-tcp_validate_incoming.patch +tcp-rfc-5961-5.2-blind-data-injection-attack-mitigation.patch diff --git a/queue-3.0/tcp-implement-rfc-5961-3.2.patch b/queue-3.0/tcp-implement-rfc-5961-3.2.patch new file mode 100644 index 00000000000..b93fe6bceea --- /dev/null +++ b/queue-3.0/tcp-implement-rfc-5961-3.2.patch @@ -0,0 +1,154 @@ +From 0d39f43963ef47bb3d3af0a331ba17825f07b1fb Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 17 Jul 2012 10:13:05 +0200 +Subject: tcp: implement RFC 5961 3.2 + + +From: Eric Dumazet + +[ Upstream commit 282f23c6ee343126156dd41218b22ece96d747e3 ] + +Implement the RFC 5691 mitigation against Blind +Reset attack using RST bit. + +Idea is to validate incoming RST sequence, +to match RCV.NXT value, instead of previouly accepted +window : (RCV.NXT <= SEG.SEQ < RCV.NXT+RCV.WND) + +If sequence is in window but not an exact match, send +a "challenge ACK", so that the other part can resend an +RST with the appropriate sequence. + +Add a new sysctl, tcp_challenge_ack_limit, to limit +number of challenge ACK sent per second. + +Add a new SNMP counter to count number of challenge acks sent. +(netstat -s | grep TCPChallengeACK) + +Signed-off-by: Eric Dumazet +Cc: Kiran Kumar Kella +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + Documentation/networking/ip-sysctl.txt | 5 +++++ + include/linux/snmp.h | 1 + + include/net/tcp.h | 1 + + net/ipv4/proc.c | 1 + + net/ipv4/sysctl_net_ipv4.c | 7 +++++++ + net/ipv4/tcp_input.c | 31 ++++++++++++++++++++++++++++++- + 6 files changed, 45 insertions(+), 1 deletion(-) + +--- a/Documentation/networking/ip-sysctl.txt ++++ b/Documentation/networking/ip-sysctl.txt +@@ -534,6 +534,11 @@ tcp_thin_dupack - BOOLEAN + Documentation/networking/tcp-thin.txt + Default: 0 + ++tcp_challenge_ack_limit - INTEGER ++ Limits number of Challenge ACK sent per second, as recommended ++ in RFC 5961 (Improving TCP's Robustness to Blind In-Window Attacks) ++ Default: 100 ++ + UDP variables: + + udp_mem - vector of 3 INTEGERs: min, pressure, max +--- a/include/linux/snmp.h ++++ b/include/linux/snmp.h +@@ -231,6 +231,7 @@ enum + LINUX_MIB_TCPDEFERACCEPTDROP, + LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ + LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ ++ LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ + __LINUX_MIB_MAX + }; + +--- a/include/net/tcp.h ++++ b/include/net/tcp.h +@@ -246,6 +246,7 @@ extern int sysctl_tcp_max_ssthresh; + extern int sysctl_tcp_cookie_size; + extern int sysctl_tcp_thin_linear_timeouts; + extern int sysctl_tcp_thin_dupack; ++extern int sysctl_tcp_challenge_ack_limit; + + extern atomic_long_t tcp_memory_allocated; + extern struct percpu_counter tcp_sockets_allocated; +--- a/net/ipv4/proc.c ++++ b/net/ipv4/proc.c +@@ -254,6 +254,7 @@ static const struct snmp_mib snmp4_net_l + SNMP_MIB_ITEM("TCPDeferAcceptDrop", LINUX_MIB_TCPDEFERACCEPTDROP), + SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), + SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), ++ SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK), + SNMP_MIB_SENTINEL + }; + +--- a/net/ipv4/sysctl_net_ipv4.c ++++ b/net/ipv4/sysctl_net_ipv4.c +@@ -566,6 +566,13 @@ static struct ctl_table ipv4_table[] = { + .mode = 0644, + .proc_handler = proc_dointvec + }, ++ { ++ .procname = "tcp_challenge_ack_limit", ++ .data = &sysctl_tcp_challenge_ack_limit, ++ .maxlen = sizeof(int), ++ .mode = 0644, ++ .proc_handler = proc_dointvec ++ }, + #ifdef CONFIG_NET_DMA + { + .procname = "tcp_dma_copybreak", +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -86,6 +86,9 @@ int sysctl_tcp_app_win __read_mostly = 3 + int sysctl_tcp_adv_win_scale __read_mostly = 1; + EXPORT_SYMBOL(sysctl_tcp_adv_win_scale); + ++/* rfc5961 challenge ack rate limiting */ ++int sysctl_tcp_challenge_ack_limit = 100; ++ + int sysctl_tcp_stdurg __read_mostly; + int sysctl_tcp_rfc1337 __read_mostly; + int sysctl_tcp_max_orphans __read_mostly = NR_FILE; +@@ -5165,6 +5168,23 @@ out: + } + #endif /* CONFIG_NET_DMA */ + ++static void tcp_send_challenge_ack(struct sock *sk) ++{ ++ /* unprotected vars, we dont care of overwrites */ ++ static u32 challenge_timestamp; ++ static unsigned int challenge_count; ++ u32 now = jiffies / HZ; ++ ++ if (now != challenge_timestamp) { ++ challenge_timestamp = now; ++ challenge_count = 0; ++ } ++ if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { ++ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); ++ tcp_send_ack(sk); ++ } ++} ++ + /* Does PAWS and seqno based validation of an incoming segment, flags will + * play significant role here. + */ +@@ -5201,7 +5221,16 @@ static int tcp_validate_incoming(struct + + /* Step 2: check RST bit */ + if (th->rst) { +- tcp_reset(sk); ++ /* RFC 5961 3.2 : ++ * If sequence number exactly matches RCV.NXT, then ++ * RESET the connection ++ * else ++ * Send a challenge ACK ++ */ ++ if (TCP_SKB_CB(skb)->seq == tp->rcv_nxt) ++ tcp_reset(sk); ++ else ++ tcp_send_challenge_ack(sk); + goto discard; + } + diff --git a/queue-3.0/tcp-implement-rfc-5961-4.2.patch b/queue-3.0/tcp-implement-rfc-5961-4.2.patch new file mode 100644 index 00000000000..4a16eee1ee4 --- /dev/null +++ b/queue-3.0/tcp-implement-rfc-5961-4.2.patch @@ -0,0 +1,152 @@ +From c273d8204931e8a0be07e04dcf6b00fb73532db3 Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 17 Jul 2012 01:41:30 +0000 +Subject: tcp: implement RFC 5961 4.2 + + +From: Eric Dumazet + +[ Upstream commit 0c24604b68fc7810d429d6c3657b6f148270e528 ] + +Implement the RFC 5691 mitigation against Blind +Reset attack using SYN bit. + +Section 4.2 of RFC 5961 advises to send a Challenge ACK and drop +incoming packet, instead of resetting the session. + +Add a new SNMP counter to count number of challenge acks sent +in response to SYN packets. +(netstat -s | grep TCPSYNChallenge) + +Remove obsolete TCPAbortOnSyn, since we no longer abort a TCP session +because of a SYN flag. + +Signed-off-by: Eric Dumazet +Cc: Kiran Kumar Kella +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + include/linux/snmp.h | 2 +- + net/ipv4/proc.c | 2 +- + net/ipv4/tcp_input.c | 32 +++++++++++++++----------------- + 3 files changed, 17 insertions(+), 19 deletions(-) + +--- a/include/linux/snmp.h ++++ b/include/linux/snmp.h +@@ -209,7 +209,6 @@ enum + LINUX_MIB_TCPDSACKOFOSENT, /* TCPDSACKOfoSent */ + LINUX_MIB_TCPDSACKRECV, /* TCPDSACKRecv */ + LINUX_MIB_TCPDSACKOFORECV, /* TCPDSACKOfoRecv */ +- LINUX_MIB_TCPABORTONSYN, /* TCPAbortOnSyn */ + LINUX_MIB_TCPABORTONDATA, /* TCPAbortOnData */ + LINUX_MIB_TCPABORTONCLOSE, /* TCPAbortOnClose */ + LINUX_MIB_TCPABORTONMEMORY, /* TCPAbortOnMemory */ +@@ -232,6 +231,7 @@ enum + LINUX_MIB_IPRPFILTER, /* IP Reverse Path Filter (rp_filter) */ + LINUX_MIB_TCPTIMEWAITOVERFLOW, /* TCPTimeWaitOverflow */ + LINUX_MIB_TCPCHALLENGEACK, /* TCPChallengeACK */ ++ LINUX_MIB_TCPSYNCHALLENGE, /* TCPSYNChallenge */ + __LINUX_MIB_MAX + }; + +--- a/net/ipv4/proc.c ++++ b/net/ipv4/proc.c +@@ -232,7 +232,6 @@ static const struct snmp_mib snmp4_net_l + SNMP_MIB_ITEM("TCPDSACKOfoSent", LINUX_MIB_TCPDSACKOFOSENT), + SNMP_MIB_ITEM("TCPDSACKRecv", LINUX_MIB_TCPDSACKRECV), + SNMP_MIB_ITEM("TCPDSACKOfoRecv", LINUX_MIB_TCPDSACKOFORECV), +- SNMP_MIB_ITEM("TCPAbortOnSyn", LINUX_MIB_TCPABORTONSYN), + SNMP_MIB_ITEM("TCPAbortOnData", LINUX_MIB_TCPABORTONDATA), + SNMP_MIB_ITEM("TCPAbortOnClose", LINUX_MIB_TCPABORTONCLOSE), + SNMP_MIB_ITEM("TCPAbortOnMemory", LINUX_MIB_TCPABORTONMEMORY), +@@ -255,6 +254,7 @@ static const struct snmp_mib snmp4_net_l + SNMP_MIB_ITEM("IPReversePathFilter", LINUX_MIB_IPRPFILTER), + SNMP_MIB_ITEM("TCPTimeWaitOverflow", LINUX_MIB_TCPTIMEWAITOVERFLOW), + SNMP_MIB_ITEM("TCPChallengeACK", LINUX_MIB_TCPCHALLENGEACK), ++ SNMP_MIB_ITEM("TCPSYNChallenge", LINUX_MIB_TCPSYNCHALLENGE), + SNMP_MIB_SENTINEL + }; + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5188,8 +5188,8 @@ static void tcp_send_challenge_ack(struc + /* Does PAWS and seqno based validation of an incoming segment, flags will + * play significant role here. + */ +-static int tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, +- struct tcphdr *th, int syn_inerr) ++static bool tcp_validate_incoming(struct sock *sk, struct sk_buff *skb, ++ struct tcphdr *th, int syn_inerr) + { + u8 *hash_location; + struct tcp_sock *tp = tcp_sk(sk); +@@ -5241,20 +5241,22 @@ static int tcp_validate_incoming(struct + + /* step 3: check security and precedence [ignored] */ + +- /* step 4: Check for a SYN in window. */ +- if (th->syn && !before(TCP_SKB_CB(skb)->seq, tp->rcv_nxt)) { ++ /* step 4: Check for a SYN ++ * RFC 5691 4.2 : Send a challenge ack ++ */ ++ if (th->syn) { + if (syn_inerr) + TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); +- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPABORTONSYN); +- tcp_reset(sk); +- return -1; ++ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNCHALLENGE); ++ tcp_send_challenge_ack(sk); ++ goto discard; + } + +- return 1; ++ return true; + + discard: + __kfree_skb(skb); +- return 0; ++ return false; + } + + /* +@@ -5284,7 +5286,6 @@ int tcp_rcv_established(struct sock *sk, + struct tcphdr *th, unsigned len) + { + struct tcp_sock *tp = tcp_sk(sk); +- int res; + + /* + * Header prediction. +@@ -5464,9 +5465,8 @@ slow_path: + * Standard slow path. + */ + +- res = tcp_validate_incoming(sk, skb, th, 1); +- if (res <= 0) +- return -res; ++ if (!tcp_validate_incoming(sk, skb, th, 1)) ++ return 0; + + step5: + if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) +@@ -5776,7 +5776,6 @@ int tcp_rcv_state_process(struct sock *s + struct tcp_sock *tp = tcp_sk(sk); + struct inet_connection_sock *icsk = inet_csk(sk); + int queued = 0; +- int res; + + tp->rx_opt.saw_tstamp = 0; + +@@ -5831,9 +5830,8 @@ int tcp_rcv_state_process(struct sock *s + return 0; + } + +- res = tcp_validate_incoming(sk, skb, th, 0); +- if (res <= 0) +- return -res; ++ if (!tcp_validate_incoming(sk, skb, th, 0)) ++ return 0; + + /* step 5: check the ACK field */ + if (th->ack) { diff --git a/queue-3.0/tcp-refine-syn-handling-in-tcp_validate_incoming.patch b/queue-3.0/tcp-refine-syn-handling-in-tcp_validate_incoming.patch new file mode 100644 index 00000000000..e8b923e1148 --- /dev/null +++ b/queue-3.0/tcp-refine-syn-handling-in-tcp_validate_incoming.patch @@ -0,0 +1,52 @@ +From 3e4726b5d8d90396d1ce6adbb8416c04479666bb Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 17 Jul 2012 12:29:30 +0000 +Subject: tcp: refine SYN handling in tcp_validate_incoming + + +From: Eric Dumazet + +[ Upstream commit e371589917011efe6ff8c7dfb4e9e81934ac5855 ] + +Followup of commit 0c24604b68fc (tcp: implement RFC 5961 4.2) + +As reported by Vijay Subramanian, we should send a challenge ACK +instead of a dup ack if a SYN flag is set on a packet received out of +window. + +This permits the ratelimiting to work as intended, and to increase +correct SNMP counters. + +Suggested-by: Vijay Subramanian +Signed-off-by: Eric Dumazet +Acked-by: Vijay Subramanian +Cc: Kiran Kumar Kella +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 6 +++++- + 1 file changed, 5 insertions(+), 1 deletion(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5214,8 +5214,11 @@ static bool tcp_validate_incoming(struct + * an acknowledgment should be sent in reply (unless the RST + * bit is set, if so drop the segment and return)". + */ +- if (!th->rst) ++ if (!th->rst) { ++ if (th->syn) ++ goto syn_challenge; + tcp_send_dupack(sk, skb); ++ } + goto discard; + } + +@@ -5245,6 +5248,7 @@ static bool tcp_validate_incoming(struct + * RFC 5691 4.2 : Send a challenge ack + */ + if (th->syn) { ++syn_challenge: + if (syn_inerr) + TCP_INC_STATS_BH(sock_net(sk), TCP_MIB_INERRS); + NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPSYNCHALLENGE); diff --git a/queue-3.0/tcp-rfc-5961-5.2-blind-data-injection-attack-mitigation.patch b/queue-3.0/tcp-rfc-5961-5.2-blind-data-injection-attack-mitigation.patch new file mode 100644 index 00000000000..a2891db1bbe --- /dev/null +++ b/queue-3.0/tcp-rfc-5961-5.2-blind-data-injection-attack-mitigation.patch @@ -0,0 +1,99 @@ +From d0c918f5163e2ce743146675d2c12ac315b69eeb Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Sun, 21 Oct 2012 19:57:11 +0000 +Subject: tcp: RFC 5961 5.2 Blind Data Injection Attack Mitigation + + +From: Eric Dumazet + +[ Upstream commit 354e4aa391ed50a4d827ff6fc11e0667d0859b25 ] + +RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] + + All TCP stacks MAY implement the following mitigation. TCP stacks + that implement this mitigation MUST add an additional input check to + any incoming segment. The ACK value is considered acceptable only if + it is in the range of ((SND.UNA - MAX.SND.WND) <= SEG.ACK <= + SND.NXT). All incoming segments whose ACK value doesn't satisfy the + above condition MUST be discarded and an ACK sent back. + +Move tcp_send_challenge_ack() before tcp_ack() to avoid a forward +declaration. + +Signed-off-by: Eric Dumazet +Cc: Neal Cardwell +Cc: Yuchung Cheng +Cc: Jerry Chu +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 43 +++++++++++++++++++++++++------------------ + 1 file changed, 25 insertions(+), 18 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -3636,6 +3636,24 @@ static int tcp_process_frto(struct sock + return 0; + } + ++/* RFC 5961 7 [ACK Throttling] */ ++static void tcp_send_challenge_ack(struct sock *sk) ++{ ++ /* unprotected vars, we dont care of overwrites */ ++ static u32 challenge_timestamp; ++ static unsigned int challenge_count; ++ u32 now = jiffies / HZ; ++ ++ if (now != challenge_timestamp) { ++ challenge_timestamp = now; ++ challenge_count = 0; ++ } ++ if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { ++ NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); ++ tcp_send_ack(sk); ++ } ++} ++ + /* This routine deals with incoming acks, but not outgoing ones. */ + static int tcp_ack(struct sock *sk, struct sk_buff *skb, int flag) + { +@@ -3652,8 +3670,14 @@ static int tcp_ack(struct sock *sk, stru + /* If the ack is older than previous acks + * then we can probably ignore it. + */ +- if (before(ack, prior_snd_una)) ++ if (before(ack, prior_snd_una)) { ++ /* RFC 5961 5.2 [Blind Data Injection Attack].[Mitigation] */ ++ if (before(ack, prior_snd_una - tp->max_window)) { ++ tcp_send_challenge_ack(sk); ++ return -1; ++ } + goto old_ack; ++ } + + /* If the ack includes data we haven't sent yet, discard + * this segment (RFC793 Section 3.9). +@@ -5168,23 +5192,6 @@ out: + } + #endif /* CONFIG_NET_DMA */ + +-static void tcp_send_challenge_ack(struct sock *sk) +-{ +- /* unprotected vars, we dont care of overwrites */ +- static u32 challenge_timestamp; +- static unsigned int challenge_count; +- u32 now = jiffies / HZ; +- +- if (now != challenge_timestamp) { +- challenge_timestamp = now; +- challenge_count = 0; +- } +- if (++challenge_count <= sysctl_tcp_challenge_ack_limit) { +- NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPCHALLENGEACK); +- tcp_send_ack(sk); +- } +-} +- + /* Does PAWS and seqno based validation of an incoming segment, flags will + * play significant role here. + */ diff --git a/queue-3.0/tcp-tcp_replace_ts_recent-should-not-be-called-from-tcp_validate_incoming.patch b/queue-3.0/tcp-tcp_replace_ts_recent-should-not-be-called-from-tcp_validate_incoming.patch new file mode 100644 index 00000000000..151786fbe43 --- /dev/null +++ b/queue-3.0/tcp-tcp_replace_ts_recent-should-not-be-called-from-tcp_validate_incoming.patch @@ -0,0 +1,74 @@ +From e5cf6017a12d2941a9b98ef7e50aa3816d98ee6a Mon Sep 17 00:00:00 2001 +From: Eric Dumazet +Date: Tue, 13 Nov 2012 05:37:18 +0000 +Subject: tcp: tcp_replace_ts_recent() should not be called from tcp_validate_incoming() + + +From: Eric Dumazet + +[ Upstream commit bd090dfc634ddd711a5fbd0cadc6e0ab4977bcaf ] + +We added support for RFC 5961 in latest kernels but TCP fails +to perform exhaustive check of ACK sequence. + +We can update our view of peer tsval from a frame that is +later discarded by tcp_ack() + +This makes timestamps enabled sessions vulnerable to injection of +a high tsval : peers start an ACK storm, since the victim +sends a dupack each time it receives an ACK from the other peer. + +As tcp_validate_incoming() is called before tcp_ack(), we should +not peform tcp_replace_ts_recent() from it, and let callers do it +at the right time. + +Signed-off-by: Eric Dumazet +Cc: Neal Cardwell +Cc: Yuchung Cheng +Cc: Nandita Dukkipati +Cc: H.K. Jerry Chu +Cc: Romain Francoise +Signed-off-by: David S. Miller +Signed-off-by: Greg Kroah-Hartman +--- + net/ipv4/tcp_input.c | 15 ++++++++++----- + 1 file changed, 10 insertions(+), 5 deletions(-) + +--- a/net/ipv4/tcp_input.c ++++ b/net/ipv4/tcp_input.c +@@ -5237,11 +5237,6 @@ static bool tcp_validate_incoming(struct + goto discard; + } + +- /* ts_recent update must be made after we are sure that the packet +- * is in window. +- */ +- tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); +- + /* step 3: check security and precedence [ignored] */ + + /* step 4: Check for a SYN +@@ -5476,6 +5471,11 @@ step5: + if (th->ack && tcp_ack(sk, skb, FLAG_SLOWPATH) < 0) + goto discard; + ++ /* ts_recent update must be made after we are sure that the packet ++ * is in window. ++ */ ++ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); ++ + tcp_rcv_rtt_measure_ts(sk, skb); + + /* Process urgent data. */ +@@ -5952,6 +5952,11 @@ int tcp_rcv_state_process(struct sock *s + } else + goto discard; + ++ /* ts_recent update must be made after we are sure that the packet ++ * is in window. ++ */ ++ tcp_replace_ts_recent(tp, TCP_SKB_CB(skb)->seq); ++ + /* step 6: check the URG bit */ + tcp_urg(sk, skb, th); +