diff options
author | Reshetova, Elena <elena.reshetova@intel.com> | 2017-07-04 15:53:05 +0300 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-07-04 22:35:16 +0100 |
commit | 2512775985969a3dadb09670701f0c16499ee784 (patch) | |
tree | f4da992f7040901e2ce7d7ea26e5e32b94dac686 | |
parent | e00bdbefab731638c0764cf1b9b7398bfbf2bd99 (diff) | |
download | linux-2512775985969a3dadb09670701f0c16499ee784.tar.bz2 |
net, bridge: convert net_bridge_vlan.refcnt from atomic_t to refcount_t
refcount_t type and corresponding API should be
used instead of atomic_t when the variable is used as
a reference counter. This allows to avoid accidental
refcounter overflows that might lead to use-after-free
situations.
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Kees Cook <keescook@chromium.org>
Signed-off-by: David Windsor <dwindsor@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/bridge/br_private.h | 3 | ||||
-rw-r--r-- | net/bridge/br_vlan.c | 8 |
2 files changed, 6 insertions, 5 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index c18682f804a0..fd9ee73e0a6d 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -21,6 +21,7 @@ #include <net/ip6_fib.h> #include <linux/if_vlan.h> #include <linux/rhashtable.h> +#include <linux/refcount.h> #define BR_HASH_BITS 8 #define BR_HASH_SIZE (1 << BR_HASH_BITS) @@ -127,7 +128,7 @@ struct net_bridge_vlan { struct net_bridge_port *port; }; union { - atomic_t refcnt; + refcount_t refcnt; struct net_bridge_vlan *brvlan; }; diff --git a/net/bridge/br_vlan.c b/net/bridge/br_vlan.c index 26a1a56639b2..233a30040c91 100644 --- a/net/bridge/br_vlan.c +++ b/net/bridge/br_vlan.c @@ -158,7 +158,7 @@ static struct net_bridge_vlan *br_vlan_get_master(struct net_bridge *br, u16 vid if (WARN_ON(!masterv)) return NULL; } - atomic_inc(&masterv->refcnt); + refcount_inc(&masterv->refcnt); return masterv; } @@ -182,7 +182,7 @@ static void br_vlan_put_master(struct net_bridge_vlan *masterv) return; vg = br_vlan_group(masterv->br); - if (atomic_dec_and_test(&masterv->refcnt)) { + if (refcount_dec_and_test(&masterv->refcnt)) { rhashtable_remove_fast(&vg->vlan_hash, &masterv->vnode, br_vlan_rht_params); __vlan_del_list(masterv); @@ -573,7 +573,7 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) br_err(br, "failed insert local address into bridge forwarding table\n"); return ret; } - atomic_inc(&vlan->refcnt); + refcount_inc(&vlan->refcnt); vlan->flags |= BRIDGE_VLAN_INFO_BRENTRY; vg->num_vlans++; } @@ -595,7 +595,7 @@ int br_vlan_add(struct net_bridge *br, u16 vid, u16 flags) vlan->flags &= ~BRIDGE_VLAN_INFO_PVID; vlan->br = br; if (flags & BRIDGE_VLAN_INFO_BRENTRY) - atomic_set(&vlan->refcnt, 1); + refcount_set(&vlan->refcnt, 1); ret = __vlan_add(vlan, flags); if (ret) { free_percpu(vlan->stats); |