summaryrefslogtreecommitdiffstats
path: root/sys-kernel/boest-v4.14.78/0004-TCP-add-a-sysctl-to-disable-simultaneous-connection-.patch
blob: 5a8cb415ed6ff8a68b7513ee3242db19f48f3b72 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
From 350a4f861577e391013be0e3644a8e6b9e20c5ff Mon Sep 17 00:00:00 2001
From: Willy Tarreau <w@1wt.eu>
Date: Wed, 8 Oct 2008 10:00:42 +0200
Subject: [PATCH 04/18] TCP: add a sysctl to disable simultaneous connection
 opening.


Strict implementation of RFC793 (TCP) requires support for a feature
called "simultaneous connect", which allows two clients to connect to
each other without anyone entering a listening state.  While almost
never used, and supported by few OSes, Linux supports this feature.


However, it introduces a weakness in the protocol which makes it very
easy for an attacker to prevent a client from connecting to a known
server. The attacker only has to guess the source port to shut down
the client connection during its establishment. The impact is limited,
but it may be used to prevent an antivirus or IPS from fetching updates
and not detecting an attack, or to prevent an SSL gateway from fetching
a CRL for example.


This patch provides a new sysctl "tcp_simult_connect" to enable or disable
support for this useless feature. It comes disabled by default.


Hundreds of systems running with that feature disabled for more than 4 years
have never encountered an application which requires it. It is almost never
supported by firewalls BTW.

From http://linux.1wt.eu/alix/kernel-src/2.6.27-wt11/patches-2.6.27-wt11.tar.bz2


Reviewed-by: Bertrand Jacquin <bertrand@jacquin.bzh>


Signed-off-by: Willy Tarreau <w@1wt.eu>
Signed-off-by: Bertrand Jacquin <bertrand@jacquin.bzh>
---
 Documentation/networking/ip-sysctl.txt | 22 ++++++++++++++++++++++
 include/net/tcp.h                      |  1 +
 include/uapi/linux/sysctl.h            |  1 +
 net/ipv4/sysctl_net_ipv4.c             |  7 +++++++
 net/ipv4/tcp_input.c                   |  6 +++++-
 5 files changed, 36 insertions(+), 1 deletion(-)


diff --git a/Documentation/networking/ip-sysctl.txt b/Documentation/networking/ip-sysctl.txt
index 7cb0aa9a12f6..b660c8913be5 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -190,6 +190,28 @@ inet_peer_maxttl - INTEGER

 
 TCP variables:
 
+tcp_simult_connect - BOOLEAN
+	Enables TCP simultaneous connect feature conforming to RFC793.
+	Strict implementation of RFC793 (TCP) requires support for a feature
+	called "simultaneous connect", which allows two clients to connect to
+	each other without anyone entering a listening state.  While almost
+	never used, and supported by few OSes, Linux supports this feature.
+
+	However, it introduces a weakness in the protocol which makes it very
+	easy for an attacker to prevent a client from connecting to a known
+	server. The attacker only has to guess the source port to shut down
+	the client connection during its establishment. The impact is limited,
+	but it may be used to prevent an antivirus or IPS from fetching updates
+	and not detecting an attack, or to prevent an SSL gateway from fetching
+	a CRL for example.
+
+	If you want absolute compatibility with any possible application,
+	you should set it to 1. If you prefer to enhance security on your
+	systems you'd better let it to 0. After four years of usage on
+	hundreds of systems, no application was ever found to require this
+	feature, which is not even supported by most firewalls.
+	Default: 0
+
 somaxconn - INTEGER
 	Limit of socket listen() backlog, known in userspace as SOMAXCONN.
 	Defaults to 128.  See also tcp_max_syn_backlog for additional tuning
diff --git a/include/net/tcp.h b/include/net/tcp.h
index f9e18cb4989e..49ade076ac84 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -261,6 +261,7 @@ extern int sysctl_tcp_moderate_rcvbuf;
 extern int sysctl_tcp_tso_win_divisor;
 extern int sysctl_tcp_workaround_signed_windows;
 extern int sysctl_tcp_slow_start_after_idle;
+extern int sysctl_tcp_simult_connect;
 extern int sysctl_tcp_thin_linear_timeouts;
 extern int sysctl_tcp_thin_dupack;
 extern int sysctl_tcp_early_retrans;
diff --git a/include/uapi/linux/sysctl.h b/include/uapi/linux/sysctl.h
index 0f272818a4d2..52dea65fa6c2 100644
--- a/include/uapi/linux/sysctl.h
+++ b/include/uapi/linux/sysctl.h
@@ -425,6 +425,7 @@ enum
 	NET_TCP_ALLOWED_CONG_CONTROL=123,
 	NET_TCP_MAX_SSTHRESH=124,
 	NET_TCP_FRTO_RESPONSE=125,
+	NET_TCP_SIMULT_CONNECT=126,
 };

 
 enum {
diff --git a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
index d82e8344fc54..a98824f99992 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -508,6 +508,13 @@ static struct ctl_table ipv4_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_doulongvec_minmax,
 	},
+	{
+		.procname	= "tcp_simult_connect",
+		.data		= &sysctl_tcp_simult_connect,
+		.maxlen		= sizeof(int),
+		.mode		= 0644,
+		.proc_handler	= &proc_dointvec,
+	},
 	{
 		.procname	= "tcp_wmem",
 		.data		= &sysctl_tcp_wmem,
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index e24c0d7adf65..dcde140b207f 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -95,6 +95,7 @@ int sysctl_tcp_min_rtt_wlen __read_mostly = 300;
 int sysctl_tcp_moderate_rcvbuf __read_mostly = 1;
 int sysctl_tcp_early_retrans __read_mostly = 3;
 int sysctl_tcp_invalid_ratelimit __read_mostly = HZ/2;
+int sysctl_tcp_simult_connect __read_mostly;
 
 #define FLAG_DATA		0x01 /* Incoming frame contained data.		*/
 #define FLAG_WIN_UPDATE		0x02 /* Incoming ACK was a window update.	*/
@@ -5816,10 +5817,13 @@ static int tcp_rcv_synsent_state_process(struct sock *sk, struct sk_buff *skb,
 	    tcp_paws_reject(&tp->rx_opt, 0))
 		goto discard_and_undo;

 
-	if (th->syn) {
+	if (th->syn && sysctl_tcp_simult_connect) {
 		/* We see SYN without ACK. It is attempt of
 		 * simultaneous connect with crossed SYNs.
 		 * Particularly, it can be connect to self.
+		 * This feature is disabled by default as it introduces
+		 * weakness in the protocol. It can be enabled by a
+		 * sysctl.
 		 */
 		tcp_set_state(sk, TCP_SYN_RECV);