mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-07 19:30:30 +09:00
tcp: implement RFC 5961 3.2
[ Upstream commit 282f23c6ee ]
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 <edumazet@google.com>
Cc: Kiran Kumar Kella <kkiran@broadcom.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
9b79271d99
commit
86791bbfe5
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -254,6 +254,7 @@ static const struct snmp_mib snmp4_net_list[] = {
|
||||
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
|
||||
};
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -86,6 +86,9 @@ int sysctl_tcp_app_win __read_mostly = 31;
|
||||
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 sock *sk, struct sk_buff *skb,
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user