summaryrefslogtreecommitdiffstats
path: root/sys-kernel/boest-v4.9.135/0004-TCP-add-a-sysctl-to-disable-simultaneous-connection-.patch
blob: d0afa0bfa59664709f9c7902700bc3d813c65f05 (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 0606862b6a91d736baaee44006d6b218c515dca8 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/21] 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 86f605e87250..42ed90b47141 100644
--- a/Documentation/networking/ip-sysctl.txt
+++ b/Documentation/networking/ip-sysctl.txt
@@ -179,6 +179,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 47cd347d2021..6e7feea0ffe2 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -260,6 +260,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 d2b12152e358..e05efade4086 100644
--- a/include/uapi/linux/sysctl.h
+++ b/include/uapi/linux/sysctl.h
@@ -424,6 +424,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 024ab833557d..1e535fa73f4c 100644
--- a/net/ipv4/sysctl_net_ipv4.c
+++ b/net/ipv4/sysctl_net_ipv4.c
@@ -409,6 +409,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 dbb153c6b21a..8ffc81376e0e 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -94,6 +94,7 @@ int sysctl_tcp_rfc1337 __read_mostly;
 int sysctl_tcp_max_orphans __read_mostly = NR_FILE;
 int sysctl_tcp_frto __read_mostly = 2;
 int sysctl_tcp_min_rtt_wlen __read_mostly = 300;
+int sysctl_tcp_simult_connect __read_mostly;
 
 int sysctl_tcp_thin_dupack __read_mostly;
 
@@ -5872,10 +5873,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);