summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2019-10-23 12:53:03 -0400
committerSimon Horman <horms@verge.net.au>2019-10-24 05:56:02 -0400
commitc24b75e0f9239e78105f81c5f03a751641eb07ef (patch)
tree25b22e73798a8b701d8ccd56ed61de5ba4b38f32 /net
parent62931f59ce9cbabb934a431f48f2f1f441c605ac (diff)
ipvs: move old_secure_tcp into struct netns_ipvs
syzbot reported the following issue : BUG: KCSAN: data-race in update_defense_level / update_defense_level read to 0xffffffff861a6260 of 4 bytes by task 3006 on cpu 1: update_defense_level+0x621/0xb30 net/netfilter/ipvs/ip_vs_ctl.c:177 defense_work_handler+0x3d/0xd0 net/netfilter/ipvs/ip_vs_ctl.c:225 process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 worker_thread+0xa0/0x800 kernel/workqueue.c:2415 kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352 write to 0xffffffff861a6260 of 4 bytes by task 7333 on cpu 0: update_defense_level+0xa62/0xb30 net/netfilter/ipvs/ip_vs_ctl.c:205 defense_work_handler+0x3d/0xd0 net/netfilter/ipvs/ip_vs_ctl.c:225 process_one_work+0x3d4/0x890 kernel/workqueue.c:2269 worker_thread+0xa0/0x800 kernel/workqueue.c:2415 kthread+0x1d4/0x200 drivers/block/aoe/aoecmd.c:1253 ret_from_fork+0x1f/0x30 arch/x86/entry/entry_64.S:352 Reported by Kernel Concurrency Sanitizer on: CPU: 0 PID: 7333 Comm: kworker/0:5 Not tainted 5.4.0-rc3+ #0 Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 01/01/2011 Workqueue: events defense_work_handler Indeed, old_secure_tcp is currently a static variable, while it needs to be a per netns variable. Fixes: a0840e2e165a ("IPVS: netns, ip_vs_ctl local vars moved to ipvs struct.") Signed-off-by: Eric Dumazet <edumazet@google.com> Reported-by: syzbot <syzkaller@googlegroups.com> Signed-off-by: Simon Horman <horms@verge.net.au>
Diffstat (limited to 'net')
-rw-r--r--net/netfilter/ipvs/ip_vs_ctl.c15
1 files changed, 7 insertions, 8 deletions
diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c
index c8f81dd15c83..3cccc88ef817 100644
--- a/net/netfilter/ipvs/ip_vs_ctl.c
+++ b/net/netfilter/ipvs/ip_vs_ctl.c
@@ -93,7 +93,6 @@ static bool __ip_vs_addr_is_local_v6(struct net *net,
93static void update_defense_level(struct netns_ipvs *ipvs) 93static void update_defense_level(struct netns_ipvs *ipvs)
94{ 94{
95 struct sysinfo i; 95 struct sysinfo i;
96 static int old_secure_tcp = 0;
97 int availmem; 96 int availmem;
98 int nomem; 97 int nomem;
99 int to_change = -1; 98 int to_change = -1;
@@ -174,35 +173,35 @@ static void update_defense_level(struct netns_ipvs *ipvs)
174 spin_lock(&ipvs->securetcp_lock); 173 spin_lock(&ipvs->securetcp_lock);
175 switch (ipvs->sysctl_secure_tcp) { 174 switch (ipvs->sysctl_secure_tcp) {
176 case 0: 175 case 0:
177 if (old_secure_tcp >= 2) 176 if (ipvs->old_secure_tcp >= 2)
178 to_change = 0; 177 to_change = 0;
179 break; 178 break;
180 case 1: 179 case 1:
181 if (nomem) { 180 if (nomem) {
182 if (old_secure_tcp < 2) 181 if (ipvs->old_secure_tcp < 2)
183 to_change = 1; 182 to_change = 1;
184 ipvs->sysctl_secure_tcp = 2; 183 ipvs->sysctl_secure_tcp = 2;
185 } else { 184 } else {
186 if (old_secure_tcp >= 2) 185 if (ipvs->old_secure_tcp >= 2)
187 to_change = 0; 186 to_change = 0;
188 } 187 }
189 break; 188 break;
190 case 2: 189 case 2:
191 if (nomem) { 190 if (nomem) {
192 if (old_secure_tcp < 2) 191 if (ipvs->old_secure_tcp < 2)
193 to_change = 1; 192 to_change = 1;
194 } else { 193 } else {
195 if (old_secure_tcp >= 2) 194 if (ipvs->old_secure_tcp >= 2)
196 to_change = 0; 195 to_change = 0;
197 ipvs->sysctl_secure_tcp = 1; 196 ipvs->sysctl_secure_tcp = 1;
198 } 197 }
199 break; 198 break;
200 case 3: 199 case 3:
201 if (old_secure_tcp < 2) 200 if (ipvs->old_secure_tcp < 2)
202 to_change = 1; 201 to_change = 1;
203 break; 202 break;
204 } 203 }
205 old_secure_tcp = ipvs->sysctl_secure_tcp; 204 ipvs->old_secure_tcp = ipvs->sysctl_secure_tcp;
206 if (to_change >= 0) 205 if (to_change >= 0)
207 ip_vs_protocol_timeout_change(ipvs, 206 ip_vs_protocol_timeout_change(ipvs,
208 ipvs->sysctl_secure_tcp > 1); 207 ipvs->sysctl_secure_tcp > 1);