net, ipv6: convert ip6addrlbl_entry.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>
This commit is contained in:
parent
d12f3827e0
commit
87078f26b6
|
@ -18,6 +18,7 @@
|
||||||
#include <linux/if_addrlabel.h>
|
#include <linux/if_addrlabel.h>
|
||||||
#include <linux/netlink.h>
|
#include <linux/netlink.h>
|
||||||
#include <linux/rtnetlink.h>
|
#include <linux/rtnetlink.h>
|
||||||
|
#include <linux/refcount.h>
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
#define ADDRLABEL(x...) printk(x)
|
#define ADDRLABEL(x...) printk(x)
|
||||||
|
@ -36,7 +37,7 @@ struct ip6addrlbl_entry {
|
||||||
int addrtype;
|
int addrtype;
|
||||||
u32 label;
|
u32 label;
|
||||||
struct hlist_node list;
|
struct hlist_node list;
|
||||||
atomic_t refcnt;
|
refcount_t refcnt;
|
||||||
struct rcu_head rcu;
|
struct rcu_head rcu;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -137,12 +138,12 @@ static void ip6addrlbl_free_rcu(struct rcu_head *h)
|
||||||
|
|
||||||
static bool ip6addrlbl_hold(struct ip6addrlbl_entry *p)
|
static bool ip6addrlbl_hold(struct ip6addrlbl_entry *p)
|
||||||
{
|
{
|
||||||
return atomic_inc_not_zero(&p->refcnt);
|
return refcount_inc_not_zero(&p->refcnt);
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
|
static inline void ip6addrlbl_put(struct ip6addrlbl_entry *p)
|
||||||
{
|
{
|
||||||
if (atomic_dec_and_test(&p->refcnt))
|
if (refcount_dec_and_test(&p->refcnt))
|
||||||
call_rcu(&p->rcu, ip6addrlbl_free_rcu);
|
call_rcu(&p->rcu, ip6addrlbl_free_rcu);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -236,7 +237,7 @@ static struct ip6addrlbl_entry *ip6addrlbl_alloc(struct net *net,
|
||||||
newp->label = label;
|
newp->label = label;
|
||||||
INIT_HLIST_NODE(&newp->list);
|
INIT_HLIST_NODE(&newp->list);
|
||||||
write_pnet(&newp->lbl_net, net);
|
write_pnet(&newp->lbl_net, net);
|
||||||
atomic_set(&newp->refcnt, 1);
|
refcount_set(&newp->refcnt, 1);
|
||||||
return newp;
|
return newp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue