summaryrefslogtreecommitdiffstats
path: root/net-plug-a-few-races.patch
blob: 5ed0339ff3ac133ea42b967250e3d09aebb4a92c (plain)
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
From ffeb56c141fc9dc2edbfa0d5c0551822180cd94a Mon Sep 17 00:00:00 2001
From: Ingo Molnar <mingo@elte.hu>
Date: Fri, 3 Jul 2009 08:30:07 -0500
Subject: [PATCH] net: plug a few races

commit 586a63770ab951230db869892deae1d09f839fdf in tip.

MUST-FIX: check the skbuff.c bit!
MUST-FIX: check the sched.c bit!

This doesn't look good. You declare it as a PER_CPU_LOCKED, but then
never use the extra lock to synchronize data.

Given that sock_proc_inuse_get() is a racy read anyway, the 'right' fix
would be to do something like:

Signed-off-by: Ingo Molnar <mingo@elte.hu>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Paul Gortmaker <paul.gortmaker@windriver.com>
---
 net/core/skbuff.c |    2 +-
 net/core/sock.c   |    7 +++++--
 2 files changed, 6 insertions(+), 3 deletions(-)

diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index 93c4e06..68c401c 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -395,7 +395,7 @@ static void skb_release_head_state(struct sk_buff *skb)
 	secpath_put(skb->sp);
 #endif
 	if (skb->destructor) {
-		WARN_ON(in_irq());
+//		WARN_ON(in_irq());
 		skb->destructor(skb);
 	}
 #if defined(CONFIG_NF_CONNTRACK) || defined(CONFIG_NF_CONNTRACK_MODULE)
diff --git a/net/core/sock.c b/net/core/sock.c
index c5812bb..4f34c99 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -2136,8 +2136,9 @@ static DECLARE_BITMAP(proto_inuse_idx, PROTO_INUSE_NR);
 #ifdef CONFIG_NET_NS
 void sock_prot_inuse_add(struct net *net, struct proto *prot, int val)
 {
-	int cpu = smp_processor_id();
+	int cpu = get_cpu();
 	per_cpu_ptr(net->core.inuse, cpu)->val[prot->inuse_idx] += val;
+	put_cpu();
 }
 EXPORT_SYMBOL_GPL(sock_prot_inuse_add);
 
@@ -2183,7 +2184,9 @@ static DEFINE_PER_CPU(struct prot_inuse, prot_inuse);
 
 void sock_prot_inuse_add(struct net *net, struct proto *prot, int val)
 {
-	__get_cpu_var(prot_inuse).val[prot->inuse_idx] += val;
+	int cpu = get_cpu();
+	per_cpu(prot_inuse, cpu).val[prot->inuse_idx] += val;
+	put_cpu();
 }
 EXPORT_SYMBOL_GPL(sock_prot_inuse_add);
 
-- 
1.7.0.4