aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q
diff options
context:
space:
mode:
authorEric Dumazet <edumazet@google.com>2013-07-18 09:35:10 -0700
committerBen Hutchings <ben@decadent.org.uk>2013-08-02 22:14:50 +0200
commitff3599bb956435966cf801d25e6c047502f3165a (patch)
tree58912b0966d9ee8f3e528e94ba2bcb34ac913e61 /net/8021q
parent729c5244dac355ca8c81f402739c218cc3212a10 (diff)
downloadkernel_samsung_smdk4412-ff3599bb956435966cf801d25e6c047502f3165a.zip
kernel_samsung_smdk4412-ff3599bb956435966cf801d25e6c047502f3165a.tar.gz
kernel_samsung_smdk4412-ff3599bb956435966cf801d25e6c047502f3165a.tar.bz2
vlan: fix a race in egress prio management
[ Upstream commit 3e3aac497513c669e1c62c71e1d552ea85c1d974 ] 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> Signed-off-by: Ben Hutchings <ben@decadent.org.uk>
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 0cccca8..b40d3da 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -72,6 +72,8 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb)
{
struct vlan_priority_tci_mapping *mp;
+ smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */
+
mp = vlan_dev_info(dev)->egress_priority_map[(skb->priority & 0xF)];
while (mp) {
if (mp->priority == skb->priority) {
@@ -232,6 +234,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev,
np->next = mp;
np->priority = skb_prio;
np->vlan_qos = vlan_qos;
+ /* Before inserting this element in hash table, make sure all its fields
+ * are committed to memory.
+ * coupled with smp_rmb() in vlan_dev_get_egress_qos_mask()
+ */
+ smp_wmb();
vlan->egress_priority_map[skb_prio & 0xF] = np;
if (vlan_qos)
vlan->nr_egress_mappings++;