aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2013-07-18 12:35:10 -0400
committerDavid S. Miller <davem@davemloft.net>2013-07-18 16:07:13 -0400
commit3e3aac497513c669e1c62c71e1d552ea85c1d974 (patch)
tree3bedf6a0f9585d0279f8a791998a29d70214fea9 /net/8021q
parentd4b812dea4a236f729526facf97df1a9d18e191c (diff)
vlan: fix a race in egress prio management
egress_priority_map[] hash table updates are protected by rtnl, and we never remove elements until device is dismantled. We have to make sure that before inserting an new element in hash table, all its fields are committed to memory or else another cpu could find corrupt values and crash. Signed-off-by: Eric Dumazet <edumazet@google.com> Cc: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q')
-rw-r--r--net/8021q/vlan_dev.c7
1 files changed, 7 insertions, 0 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 3a8c8fd63c88..1cd3d2a406f5 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -73,6 +73,8 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb)
73{ 73{
74 struct vlan_priority_tci_mapping *mp; 74 struct vlan_priority_tci_mapping *mp;
75 75
76 smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */
77
76 mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)]; 78 mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)];
77 while (mp) { 79 while (mp) {
78 if (mp->priority == skb->priority) { 80 if (mp->priority == skb->priority) {
@@ -249,6 +251,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev,
249 np->next = mp; 251 np->next = mp;
250 np->priority = skb_prio; 252 np->priority = skb_prio;
251 np->vlan_qos = vlan_qos; 253 np->vlan_qos = vlan_qos;
254 /* Before inserting this element in hash table, make sure all its fields
255 * are committed to memory.
256 * coupled with smp_rmb() in vlan_dev_get_egress_qos_mask()
257 */
258 smp_wmb();
252 vlan->egress_priority_map[skb_prio & 0xF] = np; 259 vlan->egress_priority_map[skb_prio & 0xF] = np;
253 if (vlan_qos) 260 if (vlan_qos)
254 vlan->nr_egress_mappings++; 261 vlan->nr_egress_mappings++;