Commit 3e3aac49 authored by Eric Dumazet's avatar Eric Dumazet Committed by David S. Miller

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: default avatarEric Dumazet <edumazet@google.com>
Cc: Patrick McHardy <kaber@trash.net>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d4b812de
...@@ -73,6 +73,8 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb) ...@@ -73,6 +73,8 @@ vlan_dev_get_egress_qos_mask(struct net_device *dev, struct sk_buff *skb)
{ {
struct vlan_priority_tci_mapping *mp; struct vlan_priority_tci_mapping *mp;
smp_rmb(); /* coupled with smp_wmb() in vlan_dev_set_egress_priority() */
mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)]; mp = vlan_dev_priv(dev)->egress_priority_map[(skb->priority & 0xF)];
while (mp) { while (mp) {
if (mp->priority == skb->priority) { if (mp->priority == skb->priority) {
...@@ -249,6 +251,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev, ...@@ -249,6 +251,11 @@ int vlan_dev_set_egress_priority(const struct net_device *dev,
np->next = mp; np->next = mp;
np->priority = skb_prio; np->priority = skb_prio;
np->vlan_qos = vlan_qos; 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; vlan->egress_priority_map[skb_prio & 0xF] = np;
if (vlan_qos) if (vlan_qos)
vlan->nr_egress_mappings++; vlan->nr_egress_mappings++;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment