* [PATCH 01/18] net, llc: convert llc_sap.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 02/18] net, l2tp: convert l2tp_tunnel.ref_count " Elena Reshetova
` (16 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/llc.h | 6 +++---
net/llc/llc_core.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/net/llc.h b/include/net/llc.h
index e8e61d4..dc35f25 100644
--- a/include/net/llc.h
+++ b/include/net/llc.h
@@ -55,7 +55,7 @@ struct llc_sap {
unsigned char state;
unsigned char p_bit;
unsigned char f_bit;
- atomic_t refcnt;
+ refcount_t refcnt;
int (*rcv_func)(struct sk_buff *skb,
struct net_device *dev,
struct packet_type *pt,
@@ -113,14 +113,14 @@ struct llc_sap *llc_sap_open(unsigned char lsap,
struct net_device *orig_dev));
static inline void llc_sap_hold(struct llc_sap *sap)
{
- atomic_inc(&sap->refcnt);
+ refcount_inc(&sap->refcnt);
}
void llc_sap_close(struct llc_sap *sap);
static inline void llc_sap_put(struct llc_sap *sap)
{
- if (atomic_dec_and_test(&sap->refcnt))
+ if (refcount_dec_and_test(&sap->refcnt))
llc_sap_close(sap);
}
diff --git a/net/llc/llc_core.c b/net/llc/llc_core.c
index 842851c..8904126 100644
--- a/net/llc/llc_core.c
+++ b/net/llc/llc_core.c
@@ -41,7 +41,7 @@ static struct llc_sap *llc_sap_alloc(void)
spin_lock_init(&sap->sk_lock);
for (i = 0; i < LLC_SK_LADDR_HASH_ENTRIES; i++)
INIT_HLIST_NULLS_HEAD(&sap->sk_laddr_hash[i], i);
- atomic_set(&sap->refcnt, 1);
+ refcount_set(&sap->refcnt, 1);
}
return sap;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 02/18] net, l2tp: convert l2tp_tunnel.ref_count from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
2017-03-17 11:12 ` [PATCH 01/18] net, llc: convert llc_sap.refcnt from atomic_t to refcount_t Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 03/18] net, l2tp: convert l2tp_session.ref_count " Elena Reshetova
` (15 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: peterz, jchapman, Elena Reshetova, johan.hedberg, linux-x25,
bridge, jmorris, 3chas3, Hans Liljestrand, keescook, marcel, jhs,
kuznet, linux-hams, David Windsor, yoshfuji, linux-decnet-user,
linux-kernel, ralf, kaber, linux-bluetooth, davem
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>
---
net/l2tp/l2tp_core.c | 14 +++++++-------
net/l2tp/l2tp_core.h | 3 ++-
net/l2tp/l2tp_debugfs.c | 5 ++---
net/l2tp/l2tp_ppp.c | 2 +-
4 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 8adab63..37e9cf3 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -132,12 +132,12 @@ static inline struct l2tp_net *l2tp_pernet(struct net *net)
*/
static inline void l2tp_tunnel_inc_refcount_1(struct l2tp_tunnel *tunnel)
{
- atomic_inc(&tunnel->ref_count);
+ refcount_inc(&tunnel->ref_count);
}
static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel)
{
- if (atomic_dec_and_test(&tunnel->ref_count))
+ if (refcount_dec_and_test(&tunnel->ref_count))
l2tp_tunnel_free(tunnel);
}
#ifdef L2TP_REFCNT_DEBUG
@@ -145,14 +145,14 @@ static inline void l2tp_tunnel_dec_refcount_1(struct l2tp_tunnel *tunnel)
do { \
pr_debug("l2tp_tunnel_inc_refcount: %s:%d %s: cnt=%d\n", \
__func__, __LINE__, (_t)->name, \
- atomic_read(&_t->ref_count)); \
+ refcount_read(&_t->ref_count)); \
l2tp_tunnel_inc_refcount_1(_t); \
} while (0)
#define l2tp_tunnel_dec_refcount(_t) \
do { \
pr_debug("l2tp_tunnel_dec_refcount: %s:%d %s: cnt=%d\n", \
__func__, __LINE__, (_t)->name, \
- atomic_read(&_t->ref_count)); \
+ refcount_read(&_t->ref_count)); \
l2tp_tunnel_dec_refcount_1(_t); \
} while (0)
#else
@@ -1303,7 +1303,7 @@ static void l2tp_udp_encap_destroy(struct sock *sk)
*/
static void l2tp_tunnel_free(struct l2tp_tunnel *tunnel)
{
- BUG_ON(atomic_read(&tunnel->ref_count) != 0);
+ BUG_ON(refcount_read(&tunnel->ref_count) != 0);
BUG_ON(tunnel->sock != NULL);
l2tp_info(tunnel, L2TP_MSG_CONTROL, "%s: free...\n", tunnel->name);
kfree_rcu(tunnel, rcu);
@@ -1617,7 +1617,7 @@ int l2tp_tunnel_create(struct net *net, int fd, int version, u32 tunnel_id, u32
/* Bump the reference count. The tunnel context is deleted
* only when this drops to zero. Must be done before list insertion
*/
- l2tp_tunnel_inc_refcount(tunnel);
+ refcount_set(&tunnel->ref_count, 1);
spin_lock_bh(&pn->l2tp_tunnel_list_lock);
list_add_rcu(&tunnel->list, &pn->l2tp_tunnel_list);
spin_unlock_bh(&pn->l2tp_tunnel_list_lock);
@@ -1656,7 +1656,7 @@ void l2tp_session_free(struct l2tp_session *session)
{
struct l2tp_tunnel *tunnel = session->tunnel;
- BUG_ON(atomic_read(&session->ref_count) != 0);
+ BUG_ON(refcount_read(&session->ref_count) != 0);
if (tunnel) {
BUG_ON(tunnel->magic != L2TP_TUNNEL_MAGIC);
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index aebf281..b942854 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -7,6 +7,7 @@
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
+#include <linux/refcount.h>
#ifndef _L2TP_CORE_H_
#define _L2TP_CORE_H_
@@ -177,7 +178,7 @@ struct l2tp_tunnel {
struct list_head list; /* Keep a list of all tunnels */
struct net *l2tp_net; /* the net we belong to */
- atomic_t ref_count;
+ refcount_t ref_count;
#ifdef CONFIG_DEBUG_FS
void (*show)(struct seq_file *m, void *arg);
#endif
diff --git a/net/l2tp/l2tp_debugfs.c b/net/l2tp/l2tp_debugfs.c
index 2d6760a..189e738 100644
--- a/net/l2tp/l2tp_debugfs.c
+++ b/net/l2tp/l2tp_debugfs.c
@@ -145,8 +145,7 @@ static void l2tp_dfs_seq_tunnel_show(struct seq_file *m, void *v)
"");
seq_printf(m, " %d sessions, refcnt %d/%d\n", session_count,
tunnel->sock ? atomic_read(&tunnel->sock->sk_refcnt) : 0,
- atomic_read(&tunnel->ref_count));
-
+ refcount_read(&tunnel->ref_count));
seq_printf(m, " %08x rx %ld/%ld/%ld rx %ld/%ld/%ld\n",
tunnel->debug,
atomic_long_read(&tunnel->stats.tx_packets),
@@ -171,7 +170,7 @@ static void l2tp_dfs_seq_session_show(struct seq_file *m, void *v)
"");
if (session->send_seq || session->recv_seq)
seq_printf(m, " nr %hu, ns %hu\n", session->nr, session->ns);
- seq_printf(m, " refcnt %d\n", atomic_read(&session->ref_count));
+ seq_printf(m, " refcnt %d\n", refcount_read(&session->ref_count));
seq_printf(m, " config %d/%d/%c/%c/%s/%s %08x %u\n",
session->mtu, session->mru,
session->recv_seq ? 'R' : '-',
diff --git a/net/l2tp/l2tp_ppp.c b/net/l2tp/l2tp_ppp.c
index 36cc56f..eb1a85a 100644
--- a/net/l2tp/l2tp_ppp.c
+++ b/net/l2tp/l2tp_ppp.c
@@ -1607,7 +1607,7 @@ static void pppol2tp_seq_tunnel_show(struct seq_file *m, void *v)
seq_printf(m, "\nTUNNEL '%s', %c %d\n",
tunnel->name,
(tunnel == tunnel->sock->sk_user_data) ? 'Y' : 'N',
- atomic_read(&tunnel->ref_count) - 1);
+ refcount_read(&tunnel->ref_count) - 1);
seq_printf(m, " %08x %ld/%ld/%ld %ld/%ld/%ld\n",
tunnel->debug,
atomic_long_read(&tunnel->stats.tx_packets),
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 03/18] net, l2tp: convert l2tp_session.ref_count from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
2017-03-17 11:12 ` [PATCH 01/18] net, llc: convert llc_sap.refcnt from atomic_t to refcount_t Elena Reshetova
2017-03-17 11:12 ` [PATCH 02/18] net, l2tp: convert l2tp_tunnel.ref_count " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 04/18] net, vxlan: convert vxlan_sock.refcnt " Elena Reshetova
` (14 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
net/l2tp/l2tp_core.c | 2 +-
net/l2tp/l2tp_core.h | 10 +++++-----
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/net/l2tp/l2tp_core.c b/net/l2tp/l2tp_core.c
index 37e9cf3..20ee848 100644
--- a/net/l2tp/l2tp_core.c
+++ b/net/l2tp/l2tp_core.c
@@ -1796,7 +1796,7 @@ struct l2tp_session *l2tp_session_create(int priv_size, struct l2tp_tunnel *tunn
/* Bump the reference count. The session context is deleted
* only when this drops to zero.
*/
- l2tp_session_inc_refcount(session);
+ refcount_set(&session->ref_count, 1);
l2tp_tunnel_inc_refcount(tunnel);
/* Ensure tunnel socket isn't deleted */
diff --git a/net/l2tp/l2tp_core.h b/net/l2tp/l2tp_core.h
index b942854..568b721 100644
--- a/net/l2tp/l2tp_core.h
+++ b/net/l2tp/l2tp_core.h
@@ -99,7 +99,7 @@ struct l2tp_session {
int nr_oos_count; /* For OOS recovery */
int nr_oos_count_max;
struct hlist_node hlist; /* Hash list node */
- atomic_t ref_count;
+ refcount_t ref_count;
char name[32]; /* for logging */
char ifname[IFNAMSIZ];
@@ -271,12 +271,12 @@ int l2tp_ioctl(struct sock *sk, int cmd, unsigned long arg);
*/
static inline void l2tp_session_inc_refcount_1(struct l2tp_session *session)
{
- atomic_inc(&session->ref_count);
+ refcount_inc(&session->ref_count);
}
static inline void l2tp_session_dec_refcount_1(struct l2tp_session *session)
{
- if (atomic_dec_and_test(&session->ref_count))
+ if (refcount_dec_and_test(&session->ref_count))
l2tp_session_free(session);
}
@@ -285,14 +285,14 @@ static inline void l2tp_session_dec_refcount_1(struct l2tp_session *session)
do { \
pr_debug("l2tp_session_inc_refcount: %s:%d %s: cnt=%d\n", \
__func__, __LINE__, (_s)->name, \
- atomic_read(&_s->ref_count)); \
+ refcount_read(&_s->ref_count)); \
l2tp_session_inc_refcount_1(_s); \
} while (0)
#define l2tp_session_dec_refcount(_s) \
do { \
pr_debug("l2tp_session_dec_refcount: %s:%d %s: cnt=%d\n", \
__func__, __LINE__, (_s)->name, \
- atomic_read(&_s->ref_count)); \
+ refcount_read(&_s->ref_count)); \
l2tp_session_dec_refcount_1(_s); \
} while (0)
#else
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 04/18] net, vxlan: convert vxlan_sock.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (2 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 03/18] net, l2tp: convert l2tp_session.ref_count " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 05/18] net, bluetooth: convert rfcomm_dlc.refcnt " Elena Reshetova
` (13 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: peterz, jchapman, Elena Reshetova, johan.hedberg, linux-x25,
bridge, jmorris, 3chas3, Hans Liljestrand, keescook, marcel, jhs,
kuznet, linux-hams, David Windsor, yoshfuji, linux-decnet-user,
linux-kernel, ralf, kaber, linux-bluetooth, davem
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>
---
drivers/net/vxlan.c | 10 +++++-----
include/net/vxlan.h | 2 +-
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index b791199..21a9251 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -999,11 +999,11 @@ static bool vxlan_group_used(struct vxlan_net *vn, struct vxlan_dev *dev)
/* The vxlan_sock is only used by dev, leaving group has
* no effect on other vxlan devices.
*/
- if (family == AF_INET && sock4 && atomic_read(&sock4->refcnt) == 1)
+ if (family == AF_INET && sock4 && refcount_read(&sock4->refcnt) == 1)
return false;
#if IS_ENABLED(CONFIG_IPV6)
sock6 = rtnl_dereference(dev->vn6_sock);
- if (family == AF_INET6 && sock6 && atomic_read(&sock6->refcnt) == 1)
+ if (family == AF_INET6 && sock6 && refcount_read(&sock6->refcnt) == 1)
return false;
#endif
@@ -1040,7 +1040,7 @@ static bool __vxlan_sock_release_prep(struct vxlan_sock *vs)
if (!vs)
return false;
- if (!atomic_dec_and_test(&vs->refcnt))
+ if (!refcount_dec_and_test(&vs->refcnt))
return false;
vn = net_generic(sock_net(vs->sock->sk), vxlan_net_id);
@@ -2757,7 +2757,7 @@ static struct vxlan_sock *vxlan_socket_create(struct net *net, bool ipv6,
}
vs->sock = sock;
- atomic_set(&vs->refcnt, 1);
+ refcount_set(&vs->refcnt, 1);
vs->flags = (flags & VXLAN_F_RCV_FLAGS);
spin_lock(&vn->sock_lock);
@@ -2791,7 +2791,7 @@ static int __vxlan_sock_add(struct vxlan_dev *vxlan, bool ipv6)
spin_lock(&vn->sock_lock);
vs = vxlan_find_sock(vxlan->net, ipv6 ? AF_INET6 : AF_INET,
vxlan->cfg.dst_port, vxlan->flags);
- if (vs && !atomic_add_unless(&vs->refcnt, 1, 0)) {
+ if (vs && !refcount_inc_not_zero(&vs->refcnt)) {
spin_unlock(&vn->sock_lock);
return -EBUSY;
}
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 49a5920..5c117b4 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -183,7 +183,7 @@ struct vxlan_sock {
struct hlist_node hlist;
struct socket *sock;
struct hlist_head vni_list[VNI_HASH_SIZE];
- atomic_t refcnt;
+ refcount_t refcnt;
u32 flags;
};
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 05/18] net, bluetooth: convert rfcomm_dlc.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (3 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 04/18] net, vxlan: convert vxlan_sock.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-27 14:05 ` Marcel Holtmann
2017-03-17 11:12 ` [PATCH 06/18] net, decnet: convert dn_fib_info.fib_clntref " Elena Reshetova
` (12 subsequent siblings)
17 siblings, 1 reply; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/bluetooth/rfcomm.h | 8 +++++---
net/bluetooth/rfcomm/core.c | 4 ++--
2 files changed, 7 insertions(+), 5 deletions(-)
diff --git a/include/net/bluetooth/rfcomm.h b/include/net/bluetooth/rfcomm.h
index 4190af5..da4acef 100644
--- a/include/net/bluetooth/rfcomm.h
+++ b/include/net/bluetooth/rfcomm.h
@@ -21,6 +21,8 @@
SOFTWARE IS DISCLAIMED.
*/
+#include <linux/refcount.h>
+
#ifndef __RFCOMM_H
#define __RFCOMM_H
@@ -174,7 +176,7 @@ struct rfcomm_dlc {
struct mutex lock;
unsigned long state;
unsigned long flags;
- atomic_t refcnt;
+ refcount_t refcnt;
u8 dlci;
u8 addr;
u8 priority;
@@ -247,12 +249,12 @@ struct rfcomm_dlc *rfcomm_dlc_exists(bdaddr_t *src, bdaddr_t *dst, u8 channel);
static inline void rfcomm_dlc_hold(struct rfcomm_dlc *d)
{
- atomic_inc(&d->refcnt);
+ refcount_inc(&d->refcnt);
}
static inline void rfcomm_dlc_put(struct rfcomm_dlc *d)
{
- if (atomic_dec_and_test(&d->refcnt))
+ if (refcount_dec_and_test(&d->refcnt))
rfcomm_dlc_free(d);
}
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index f7eb02f..8ebca90 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -311,7 +311,7 @@ struct rfcomm_dlc *rfcomm_dlc_alloc(gfp_t prio)
skb_queue_head_init(&d->tx_queue);
mutex_init(&d->lock);
- atomic_set(&d->refcnt, 1);
+ refcount_set(&d->refcnt, 1);
rfcomm_dlc_clear_state(d);
@@ -342,7 +342,7 @@ static void rfcomm_dlc_unlink(struct rfcomm_dlc *d)
{
struct rfcomm_session *s = d->session;
- BT_DBG("dlc %p refcnt %d session %p", d, atomic_read(&d->refcnt), s);
+ BT_DBG("dlc %p refcnt %d session %p", d, refcount_read(&d->refcnt), s);
list_del(&d->list);
d->session = NULL;
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* Re: [PATCH 05/18] net, bluetooth: convert rfcomm_dlc.refcnt from atomic_t to refcount_t
2017-03-17 11:12 ` [PATCH 05/18] net, bluetooth: convert rfcomm_dlc.refcnt " Elena Reshetova
@ 2017-03-27 14:05 ` Marcel Holtmann
0 siblings, 0 replies; 20+ messages in thread
From: Marcel Holtmann @ 2017-03-27 14:05 UTC (permalink / raw)
To: Elena Reshetova
Cc: Network Development, LKML, linux-decnet-user, David S. Miller,
James Morris, Patrick McHardy, Hideaki YOSHIFUJI,
Alexey Kuznetsov, 3chas3, ralf, stephen, jchapman, jhs, bridge,
linux-hams, linux-x25, linux-bluetooth, Johan Hedberg, peterz,
keescook, Hans Liljestrand, David Windsor
Hi Elena,
> 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>
> ---
> include/net/bluetooth/rfcomm.h | 8 +++++---
> net/bluetooth/rfcomm/core.c | 4 ++--
> 2 files changed, 7 insertions(+), 5 deletions(-)
patch has been applied to bluetooth-next tree.
Regards
Marcel
^ permalink raw reply [flat|nested] 20+ messages in thread
* [PATCH 06/18] net, decnet: convert dn_fib_info.fib_clntref from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (4 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 05/18] net, bluetooth: convert rfcomm_dlc.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 07/18] net, atm: convert atm_dev.refcnt " Elena Reshetova
` (11 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/dn_fib.h | 5 +++--
net/decnet/dn_fib.c | 6 +++---
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/net/dn_fib.h b/include/net/dn_fib.h
index f2ca135..81210a8 100644
--- a/include/net/dn_fib.h
+++ b/include/net/dn_fib.h
@@ -2,6 +2,7 @@
#define _NET_DN_FIB_H
#include <linux/netlink.h>
+#include <linux/refcount.h>
extern const struct nla_policy rtm_dn_policy[];
@@ -28,7 +29,7 @@ struct dn_fib_info {
struct dn_fib_info *fib_next;
struct dn_fib_info *fib_prev;
int fib_treeref;
- atomic_t fib_clntref;
+ refcount_t fib_clntref;
int fib_dead;
unsigned int fib_flags;
int fib_protocol;
@@ -130,7 +131,7 @@ void dn_fib_free_info(struct dn_fib_info *fi);
static inline void dn_fib_info_put(struct dn_fib_info *fi)
{
- if (atomic_dec_and_test(&fi->fib_clntref))
+ if (refcount_dec_and_test(&fi->fib_clntref))
dn_fib_free_info(fi);
}
diff --git a/net/decnet/dn_fib.c b/net/decnet/dn_fib.c
index 7af0ba61..85058c3 100644
--- a/net/decnet/dn_fib.c
+++ b/net/decnet/dn_fib.c
@@ -389,7 +389,7 @@ struct dn_fib_info *dn_fib_create_info(const struct rtmsg *r, struct nlattr *att
}
fi->fib_treeref++;
- atomic_inc(&fi->fib_clntref);
+ refcount_set(&fi->fib_clntref, 1);
spin_lock(&dn_fib_info_lock);
fi->fib_next = dn_fib_info_list;
fi->fib_prev = NULL;
@@ -425,7 +425,7 @@ int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn
switch (type) {
case RTN_NAT:
DN_FIB_RES_RESET(*res);
- atomic_inc(&fi->fib_clntref);
+ refcount_inc(&fi->fib_clntref);
return 0;
case RTN_UNICAST:
case RTN_LOCAL:
@@ -438,7 +438,7 @@ int dn_fib_semantic_match(int type, struct dn_fib_info *fi, const struct flowidn
}
if (nhsel < fi->fib_nhs) {
res->nh_sel = nhsel;
- atomic_inc(&fi->fib_clntref);
+ refcount_inc(&fi->fib_clntref);
return 0;
}
endfor_nexthops(fi);
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 07/18] net, atm: convert atm_dev.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (5 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 06/18] net, decnet: convert dn_fib_info.fib_clntref " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 08/18] net, atm: convert lec_arp_table.usage " Elena Reshetova
` (10 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/linux/atmdev.h | 7 ++++---
net/atm/proc.c | 2 +-
net/atm/resources.c | 2 +-
3 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/linux/atmdev.h b/include/linux/atmdev.h
index c1da539..2a87aea 100644
--- a/include/linux/atmdev.h
+++ b/include/linux/atmdev.h
@@ -11,6 +11,7 @@
#include <linux/uio.h>
#include <net/sock.h>
#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <uapi/linux/atmdev.h>
#ifdef CONFIG_PROC_FS
@@ -158,7 +159,7 @@ struct atm_dev {
struct k_atm_dev_stats stats; /* statistics */
char signal; /* signal status (ATM_PHY_SIG_*) */
int link_rate; /* link rate (default: OC3) */
- atomic_t refcnt; /* reference count */
+ refcount_t refcnt; /* reference count */
spinlock_t lock; /* protect internal members */
#ifdef CONFIG_PROC_FS
struct proc_dir_entry *proc_entry; /* proc entry */
@@ -261,13 +262,13 @@ static inline int atm_may_send(struct atm_vcc *vcc,unsigned int size)
static inline void atm_dev_hold(struct atm_dev *dev)
{
- atomic_inc(&dev->refcnt);
+ refcount_inc(&dev->refcnt);
}
static inline void atm_dev_put(struct atm_dev *dev)
{
- if (atomic_dec_and_test(&dev->refcnt)) {
+ if (refcount_dec_and_test(&dev->refcnt)) {
BUG_ON(!test_bit(ATM_DF_REMOVED, &dev->flags));
if (dev->ops->dev_close)
dev->ops->dev_close(dev);
diff --git a/net/atm/proc.c b/net/atm/proc.c
index bbb6461..bcb8ee5 100644
--- a/net/atm/proc.c
+++ b/net/atm/proc.c
@@ -61,7 +61,7 @@ static void atm_dev_info(struct seq_file *seq, const struct atm_dev *dev)
add_stats(seq, "0", &dev->stats.aal0);
seq_puts(seq, " ");
add_stats(seq, "5", &dev->stats.aal5);
- seq_printf(seq, "\t[%d]", atomic_read(&dev->refcnt));
+ seq_printf(seq, "\t[%d]", refcount_read(&dev->refcnt));
seq_putc(seq, '\n');
}
diff --git a/net/atm/resources.c b/net/atm/resources.c
index 0447d5d..9182447 100644
--- a/net/atm/resources.c
+++ b/net/atm/resources.c
@@ -109,7 +109,7 @@ struct atm_dev *atm_dev_register(const char *type, struct device *parent,
else
memset(&dev->flags, 0, sizeof(dev->flags));
memset(&dev->stats, 0, sizeof(dev->stats));
- atomic_set(&dev->refcnt, 1);
+ refcount_set(&dev->refcnt, 1);
if (atm_proc_dev_register(dev) < 0) {
pr_err("atm_proc_dev_register failed for dev %s\n", type);
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 08/18] net, atm: convert lec_arp_table.usage from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (6 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 07/18] net, atm: convert atm_dev.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 09/18] net, atm: convert in_cache_entry.use " Elena Reshetova
` (9 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
net/atm/lec.c | 6 +++---
net/atm/lec_arpc.h | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/net/atm/lec.c b/net/atm/lec.c
index 09cfe87..431f32c 100644
--- a/net/atm/lec.c
+++ b/net/atm/lec.c
@@ -101,12 +101,12 @@ static void lec_vcc_close(struct lec_priv *priv, struct atm_vcc *vcc);
/* must be done under lec_arp_lock */
static inline void lec_arp_hold(struct lec_arp_table *entry)
{
- atomic_inc(&entry->usage);
+ refcount_inc(&entry->usage);
}
static inline void lec_arp_put(struct lec_arp_table *entry)
{
- if (atomic_dec_and_test(&entry->usage))
+ if (refcount_dec_and_test(&entry->usage))
kfree(entry);
}
@@ -1564,7 +1564,7 @@ static struct lec_arp_table *make_entry(struct lec_priv *priv,
to_return->last_used = jiffies;
to_return->priv = priv;
skb_queue_head_init(&to_return->tx_wait);
- atomic_set(&to_return->usage, 1);
+ refcount_set(&to_return->usage, 1);
return to_return;
}
diff --git a/net/atm/lec_arpc.h b/net/atm/lec_arpc.h
index ec67435..d923f53 100644
--- a/net/atm/lec_arpc.h
+++ b/net/atm/lec_arpc.h
@@ -47,7 +47,7 @@ struct lec_arp_table {
* the length of the tlvs array
*/
struct sk_buff_head tx_wait; /* wait queue for outgoing packets */
- atomic_t usage; /* usage count */
+ refcount_t usage; /* usage count */
};
/*
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 09/18] net, atm: convert in_cache_entry.use from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (7 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 08/18] net, atm: convert lec_arp_table.usage " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 10/18] net, atm: convert eg_cache_entry.use " Elena Reshetova
` (8 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
net/atm/mpoa_caches.c | 12 ++++++------
net/atm/mpoa_caches.h | 3 ++-
2 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
index a89fdeb..05e89e9 100644
--- a/net/atm/mpoa_caches.c
+++ b/net/atm/mpoa_caches.c
@@ -40,7 +40,7 @@ static in_cache_entry *in_cache_get(__be32 dst_ip,
entry = client->in_cache;
while (entry != NULL) {
if (entry->ctrl_info.in_dst_ip == dst_ip) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_bh(&client->ingress_lock);
return entry;
}
@@ -61,7 +61,7 @@ static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip,
entry = client->in_cache;
while (entry != NULL) {
if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_bh(&client->ingress_lock);
return entry;
}
@@ -82,7 +82,7 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
entry = client->in_cache;
while (entry != NULL) {
if (entry->shortcut == vcc) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_bh(&client->ingress_lock);
return entry;
}
@@ -105,7 +105,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
dprintk("adding an ingress entry, ip = %pI4\n", &dst_ip);
- atomic_set(&entry->use, 1);
+ refcount_set(&entry->use, 1);
dprintk("new_in_cache_entry: about to lock\n");
write_lock_bh(&client->ingress_lock);
entry->next = client->in_cache;
@@ -121,7 +121,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
entry->count = 1;
entry->entry_state = INGRESS_INVALID;
entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT;
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
write_unlock_bh(&client->ingress_lock);
dprintk("new_in_cache_entry: unlocked\n");
@@ -178,7 +178,7 @@ static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc)
static void in_cache_put(in_cache_entry *entry)
{
- if (atomic_dec_and_test(&entry->use)) {
+ if (refcount_dec_and_test(&entry->use)) {
memset(entry, 0, sizeof(in_cache_entry));
kfree(entry);
}
diff --git a/net/atm/mpoa_caches.h b/net/atm/mpoa_caches.h
index 8e5f78c..38a4e7e 100644
--- a/net/atm/mpoa_caches.h
+++ b/net/atm/mpoa_caches.h
@@ -6,6 +6,7 @@
#include <linux/atm.h>
#include <linux/atmdev.h>
#include <linux/atmmpc.h>
+#include <linux/refcount.h>
struct mpoa_client;
@@ -25,7 +26,7 @@ typedef struct in_cache_entry {
struct atm_vcc *shortcut;
uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
struct in_ctrl_info ctrl_info;
- atomic_t use;
+ refcount_t use;
} in_cache_entry;
struct in_cache_ops{
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 10/18] net, atm: convert eg_cache_entry.use from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (8 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 09/18] net, atm: convert in_cache_entry.use " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 11/18] net, bridge: convert net_bridge_vlan.refcnt " Elena Reshetova
` (7 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
net/atm/mpoa_caches.c | 14 +++++++-------
net/atm/mpoa_caches.h | 2 +-
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
index 05e89e9..4ccaa16 100644
--- a/net/atm/mpoa_caches.c
+++ b/net/atm/mpoa_caches.c
@@ -339,7 +339,7 @@ static eg_cache_entry *eg_cache_get_by_cache_id(__be32 cache_id,
entry = mpc->eg_cache;
while (entry != NULL) {
if (entry->ctrl_info.cache_id == cache_id) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_irq(&mpc->egress_lock);
return entry;
}
@@ -360,7 +360,7 @@ static eg_cache_entry *eg_cache_get_by_tag(__be32 tag, struct mpoa_client *mpc)
entry = mpc->eg_cache;
while (entry != NULL) {
if (entry->ctrl_info.tag == tag) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_irqrestore(&mpc->egress_lock, flags);
return entry;
}
@@ -382,7 +382,7 @@ static eg_cache_entry *eg_cache_get_by_vcc(struct atm_vcc *vcc,
entry = mpc->eg_cache;
while (entry != NULL) {
if (entry->shortcut == vcc) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_irqrestore(&mpc->egress_lock, flags);
return entry;
}
@@ -402,7 +402,7 @@ static eg_cache_entry *eg_cache_get_by_src_ip(__be32 ipaddr,
entry = mpc->eg_cache;
while (entry != NULL) {
if (entry->latest_ip_addr == ipaddr) {
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
read_unlock_irq(&mpc->egress_lock);
return entry;
}
@@ -415,7 +415,7 @@ static eg_cache_entry *eg_cache_get_by_src_ip(__be32 ipaddr,
static void eg_cache_put(eg_cache_entry *entry)
{
- if (atomic_dec_and_test(&entry->use)) {
+ if (refcount_dec_and_test(&entry->use)) {
memset(entry, 0, sizeof(eg_cache_entry));
kfree(entry);
}
@@ -468,7 +468,7 @@ static eg_cache_entry *eg_cache_add_entry(struct k_message *msg,
dprintk("adding an egress entry, ip = %pI4, this should be our IP\n",
&msg->content.eg_info.eg_dst_ip);
- atomic_set(&entry->use, 1);
+ refcount_set(&entry->use, 1);
dprintk("new_eg_cache_entry: about to lock\n");
write_lock_irq(&client->egress_lock);
entry->next = client->eg_cache;
@@ -484,7 +484,7 @@ static eg_cache_entry *eg_cache_add_entry(struct k_message *msg,
dprintk("new_eg_cache_entry cache_id %u\n",
ntohl(entry->ctrl_info.cache_id));
dprintk("mps_ip = %pI4\n", &entry->ctrl_info.mps_ip);
- atomic_inc(&entry->use);
+ refcount_inc(&entry->use);
write_unlock_irq(&client->egress_lock);
dprintk("new_eg_cache_entry: unlocked\n");
diff --git a/net/atm/mpoa_caches.h b/net/atm/mpoa_caches.h
index 38a4e7e..30fe348 100644
--- a/net/atm/mpoa_caches.h
+++ b/net/atm/mpoa_caches.h
@@ -59,7 +59,7 @@ typedef struct eg_cache_entry{
uint16_t entry_state;
__be32 latest_ip_addr; /* The src IP address of the last packet */
struct eg_ctrl_info ctrl_info;
- atomic_t use;
+ refcount_t use;
} eg_cache_entry;
struct eg_cache_ops{
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 11/18] net, bridge: convert net_bridge_vlan.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (9 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 10/18] net, atm: convert eg_cache_entry.use " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 12/18] net, calipso: convert calipso_doi.refcount " Elena Reshetova
` (6 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
net/bridge/br_private.h | 3 ++-
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 2288fca..16cb470 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 62e68c0..e4e9e1a 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);
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 12/18] net, calipso: convert calipso_doi.refcount from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (10 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 11/18] net, bridge: convert net_bridge_vlan.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 13/18] net, sched: convert Qdisc.refcnt " Elena Reshetova
` (5 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/calipso.h | 4 ++--
net/ipv6/calipso.c | 12 ++++++------
2 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/include/net/calipso.h b/include/net/calipso.h
index b1b30cd..5f95b11 100644
--- a/include/net/calipso.h
+++ b/include/net/calipso.h
@@ -38,7 +38,7 @@
#include <linux/skbuff.h>
#include <net/netlabel.h>
#include <net/request_sock.h>
-#include <linux/atomic.h>
+#include <linux/refcount.h>
#include <asm/unaligned.h>
/* known doi values */
@@ -57,7 +57,7 @@ struct calipso_doi {
u32 doi;
u32 type;
- atomic_t refcount;
+ refcount_t refcount;
struct list_head list;
struct rcu_head rcu;
};
diff --git a/net/ipv6/calipso.c b/net/ipv6/calipso.c
index 37ac9de..997611f 100644
--- a/net/ipv6/calipso.c
+++ b/net/ipv6/calipso.c
@@ -338,7 +338,7 @@ static struct calipso_doi *calipso_doi_search(u32 doi)
struct calipso_doi *iter;
list_for_each_entry_rcu(iter, &calipso_doi_list, list)
- if (iter->doi == doi && atomic_read(&iter->refcount))
+ if (iter->doi == doi && refcount_read(&iter->refcount))
return iter;
return NULL;
}
@@ -370,7 +370,7 @@ static int calipso_doi_add(struct calipso_doi *doi_def,
if (doi_def->doi == CALIPSO_DOI_UNKNOWN)
goto doi_add_return;
- atomic_set(&doi_def->refcount, 1);
+ refcount_set(&doi_def->refcount, 1);
spin_lock(&calipso_doi_list_lock);
if (calipso_doi_search(doi_def->doi)) {
@@ -458,7 +458,7 @@ static int calipso_doi_remove(u32 doi, struct netlbl_audit *audit_info)
ret_val = -ENOENT;
goto doi_remove_return;
}
- if (!atomic_dec_and_test(&doi_def->refcount)) {
+ if (!refcount_dec_and_test(&doi_def->refcount)) {
spin_unlock(&calipso_doi_list_lock);
ret_val = -EBUSY;
goto doi_remove_return;
@@ -499,7 +499,7 @@ static struct calipso_doi *calipso_doi_getdef(u32 doi)
doi_def = calipso_doi_search(doi);
if (!doi_def)
goto doi_getdef_return;
- if (!atomic_inc_not_zero(&doi_def->refcount))
+ if (!refcount_inc_not_zero(&doi_def->refcount))
doi_def = NULL;
doi_getdef_return:
@@ -520,7 +520,7 @@ static void calipso_doi_putdef(struct calipso_doi *doi_def)
if (!doi_def)
return;
- if (!atomic_dec_and_test(&doi_def->refcount))
+ if (!refcount_dec_and_test(&doi_def->refcount))
return;
spin_lock(&calipso_doi_list_lock);
list_del_rcu(&doi_def->list);
@@ -553,7 +553,7 @@ static int calipso_doi_walk(u32 *skip_cnt,
rcu_read_lock();
list_for_each_entry_rcu(iter_doi, &calipso_doi_list, list)
- if (atomic_read(&iter_doi->refcount) > 0) {
+ if (refcount_read(&iter_doi->refcount) > 0) {
if (doi_cnt++ < *skip_cnt)
continue;
ret_val = callback(iter_doi, cb_arg);
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 13/18] net, sched: convert Qdisc.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (11 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 12/18] net, calipso: convert calipso_doi.refcount " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 14/18] net, lapb: convert lapb_cb.refcnt " Elena Reshetova
` (4 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/sch_generic.h | 3 ++-
net/sched/sch_api.c | 8 ++++----
net/sched/sch_generic.c | 8 ++++----
3 files changed, 10 insertions(+), 9 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index aeec408..cd7463f 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -8,6 +8,7 @@
#include <linux/pkt_cls.h>
#include <linux/percpu.h>
#include <linux/dynamic_queue_limits.h>
+#include <linux/refcount.h>
#include <net/gen_stats.h>
#include <net/rtnetlink.h>
@@ -93,7 +94,7 @@ struct Qdisc {
struct sk_buff *skb_bad_txq;
struct rcu_head rcu_head;
int padded;
- atomic_t refcnt;
+ refcount_t refcnt;
spinlock_t busylock ____cacheline_aligned_in_smp;
};
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index bcf49cd..806f7b5 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -828,7 +828,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
old = dev_graft_qdisc(dev_queue, new);
if (new && i > 0)
- atomic_inc(&new->refcnt);
+ refcount_inc(&new->refcnt);
if (!ingress)
qdisc_destroy(old);
@@ -839,7 +839,7 @@ static int qdisc_graft(struct net_device *dev, struct Qdisc *parent,
notify_and_destroy(net, skb, n, classid,
dev->qdisc, new);
if (new && !new->ops->attach)
- atomic_inc(&new->refcnt);
+ refcount_inc(&new->refcnt);
dev->qdisc = new ? : &noop_qdisc;
if (new && new->ops->attach)
@@ -1245,7 +1245,7 @@ static int tc_modify_qdisc(struct sk_buff *skb, struct nlmsghdr *n)
if (q == p ||
(p && check_loop(q, p, 0)))
return -ELOOP;
- atomic_inc(&q->refcnt);
+ refcount_inc(&q->refcnt);
goto graft;
} else {
if (!q)
@@ -1360,7 +1360,7 @@ static int tc_fill_qdisc(struct sk_buff *skb, struct Qdisc *q, u32 clid,
tcm->tcm_ifindex = qdisc_dev(q)->ifindex;
tcm->tcm_parent = clid;
tcm->tcm_handle = q->handle;
- tcm->tcm_info = atomic_read(&q->refcnt);
+ tcm->tcm_info = refcount_read(&q->refcnt);
if (nla_put_string(skb, TCA_KIND, q->ops->id))
goto nla_put_failure;
if (q->ops->dump && q->ops->dump(q, skb) < 0)
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index b052b27..6e0c695 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -633,7 +633,7 @@ struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
sch->dequeue = ops->dequeue;
sch->dev_queue = dev_queue;
dev_hold(dev);
- atomic_set(&sch->refcnt, 1);
+ refcount_set(&sch->refcnt, 1);
return sch;
errout:
@@ -701,7 +701,7 @@ void qdisc_destroy(struct Qdisc *qdisc)
const struct Qdisc_ops *ops = qdisc->ops;
if (qdisc->flags & TCQ_F_BUILTIN ||
- !atomic_dec_and_test(&qdisc->refcnt))
+ !refcount_dec_and_test(&qdisc->refcnt))
return;
#ifdef CONFIG_NET_SCHED
@@ -739,7 +739,7 @@ struct Qdisc *dev_graft_qdisc(struct netdev_queue *dev_queue,
spin_lock_bh(root_lock);
/* Prune old scheduler */
- if (oqdisc && atomic_read(&oqdisc->refcnt) <= 1)
+ if (oqdisc && refcount_read(&oqdisc->refcnt) <= 1)
qdisc_reset(oqdisc);
/* ... and graft new one */
@@ -785,7 +785,7 @@ static void attach_default_qdiscs(struct net_device *dev)
dev->priv_flags & IFF_NO_QUEUE) {
netdev_for_each_tx_queue(dev, attach_one_default_qdisc, NULL);
dev->qdisc = txq->qdisc_sleeping;
- atomic_inc(&dev->qdisc->refcnt);
+ refcount_inc(&dev->qdisc->refcnt);
} else {
qdisc = qdisc_create_dflt(txq, &mq_qdisc_ops, TC_H_ROOT);
if (qdisc) {
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 14/18] net, lapb: convert lapb_cb.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (12 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 13/18] net, sched: convert Qdisc.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 15/18] net, ipx: convert ipx_interface.refcnt " Elena Reshetova
` (3 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/lapb.h | 3 ++-
net/lapb/lapb_iface.c | 6 +++---
2 files changed, 5 insertions(+), 4 deletions(-)
diff --git a/include/net/lapb.h b/include/net/lapb.h
index 9510f87..85e7737 100644
--- a/include/net/lapb.h
+++ b/include/net/lapb.h
@@ -1,6 +1,7 @@
#ifndef _LAPB_H
#define _LAPB_H
#include <linux/lapb.h>
+#include <linux/refcount.h>
#define LAPB_HEADER_LEN 20 /* LAPB over Ethernet + a bit more */
@@ -101,7 +102,7 @@ struct lapb_cb {
struct lapb_frame frmr_data;
unsigned char frmr_type;
- atomic_t refcnt;
+ refcount_t refcnt;
};
/* lapb_iface.c */
diff --git a/net/lapb/lapb_iface.c b/net/lapb/lapb_iface.c
index b50b64a..e15314e 100644
--- a/net/lapb/lapb_iface.c
+++ b/net/lapb/lapb_iface.c
@@ -54,12 +54,12 @@ static void lapb_free_cb(struct lapb_cb *lapb)
static __inline__ void lapb_hold(struct lapb_cb *lapb)
{
- atomic_inc(&lapb->refcnt);
+ refcount_inc(&lapb->refcnt);
}
static __inline__ void lapb_put(struct lapb_cb *lapb)
{
- if (atomic_dec_and_test(&lapb->refcnt))
+ if (refcount_dec_and_test(&lapb->refcnt))
lapb_free_cb(lapb);
}
@@ -136,7 +136,7 @@ static struct lapb_cb *lapb_create_cb(void)
lapb->mode = LAPB_DEFAULT_MODE;
lapb->window = LAPB_DEFAULT_WINDOW;
lapb->state = LAPB_STATE_0;
- atomic_set(&lapb->refcnt, 1);
+ refcount_set(&lapb->refcnt, 1);
out:
return lapb;
}
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 15/18] net, ipx: convert ipx_interface.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (13 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 14/18] net, lapb: convert lapb_cb.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 16/18] net, ipx: convert ipx_route.refcnt " Elena Reshetova
` (2 subsequent siblings)
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/ipx.h | 7 ++++---
net/ipx/af_ipx.c | 6 +++---
net/ipx/ipx_proc.c | 2 +-
3 files changed, 8 insertions(+), 7 deletions(-)
diff --git a/include/net/ipx.h b/include/net/ipx.h
index e5cff68..2de1281 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -14,6 +14,7 @@
#include <linux/ipx.h>
#include <linux/list.h>
#include <linux/slab.h>
+#include <linux/refcount.h>
struct ipx_address {
__be32 net;
@@ -54,7 +55,7 @@ struct ipx_interface {
/* IPX address */
__be32 if_netnum;
unsigned char if_node[IPX_NODE_LEN];
- atomic_t refcnt;
+ refcount_t refcnt;
/* physical device info */
struct net_device *if_dev;
@@ -139,7 +140,7 @@ const char *ipx_device_name(struct ipx_interface *intrfc);
static __inline__ void ipxitf_hold(struct ipx_interface *intrfc)
{
- atomic_inc(&intrfc->refcnt);
+ refcount_inc(&intrfc->refcnt);
}
void ipxitf_down(struct ipx_interface *intrfc);
@@ -157,7 +158,7 @@ int ipxrtr_ioctl(unsigned int cmd, void __user *arg);
static __inline__ void ipxitf_put(struct ipx_interface *intrfc)
{
- if (atomic_dec_and_test(&intrfc->refcnt))
+ if (refcount_dec_and_test(&intrfc->refcnt))
ipxitf_down(intrfc);
}
diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
index 8a9219f..0675b4a 100644
--- a/net/ipx/af_ipx.c
+++ b/net/ipx/af_ipx.c
@@ -308,7 +308,7 @@ void ipxitf_down(struct ipx_interface *intrfc)
static void __ipxitf_put(struct ipx_interface *intrfc)
{
- if (atomic_dec_and_test(&intrfc->refcnt))
+ if (refcount_dec_and_test(&intrfc->refcnt))
__ipxitf_down(intrfc);
}
@@ -876,7 +876,7 @@ static struct ipx_interface *ipxitf_alloc(struct net_device *dev, __be32 netnum,
intrfc->if_ipx_offset = ipx_offset;
intrfc->if_sknum = IPX_MIN_EPHEMERAL_SOCKET;
INIT_HLIST_HEAD(&intrfc->if_sklist);
- atomic_set(&intrfc->refcnt, 1);
+ refcount_set(&intrfc->refcnt, 1);
spin_lock_init(&intrfc->if_sklist_lock);
}
@@ -1105,7 +1105,7 @@ static struct ipx_interface *ipxitf_auto_create(struct net_device *dev,
memcpy((char *)&(intrfc->if_node[IPX_NODE_LEN-dev->addr_len]),
dev->dev_addr, dev->addr_len);
spin_lock_init(&intrfc->if_sklist_lock);
- atomic_set(&intrfc->refcnt, 1);
+ refcount_set(&intrfc->refcnt, 1);
ipxitf_insert(intrfc);
dev_hold(dev);
}
diff --git a/net/ipx/ipx_proc.c b/net/ipx/ipx_proc.c
index c1d247e..7d75e4c 100644
--- a/net/ipx/ipx_proc.c
+++ b/net/ipx/ipx_proc.c
@@ -53,7 +53,7 @@ static int ipx_seq_interface_show(struct seq_file *seq, void *v)
seq_printf(seq, "%-11s", ipx_device_name(i));
seq_printf(seq, "%-9s", ipx_frame_name(i->if_dlink_type));
#ifdef IPX_REFCNT_DEBUG
- seq_printf(seq, "%6d", atomic_read(&i->refcnt));
+ seq_printf(seq, "%6d", refcount_read(&i->refcnt));
#endif
seq_puts(seq, "\n");
out:
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 16/18] net, ipx: convert ipx_route.refcnt from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (14 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 15/18] net, ipx: convert ipx_interface.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 17/18] net, netrom: convert nr_neigh.refcount " Elena Reshetova
2017-03-17 11:12 ` [PATCH 18/18] net, netrom: convert nr_node.refcount " Elena Reshetova
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/ipx.h | 6 +++---
net/ipx/ipx_route.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/net/ipx.h b/include/net/ipx.h
index 2de1281..af32b97 100644
--- a/include/net/ipx.h
+++ b/include/net/ipx.h
@@ -81,7 +81,7 @@ struct ipx_route {
unsigned char ir_routed;
unsigned char ir_router_node[IPX_NODE_LEN];
struct list_head node; /* node in ipx_routes list */
- atomic_t refcnt;
+ refcount_t refcnt;
};
struct ipx_cb {
@@ -164,12 +164,12 @@ static __inline__ void ipxitf_put(struct ipx_interface *intrfc)
static __inline__ void ipxrtr_hold(struct ipx_route *rt)
{
- atomic_inc(&rt->refcnt);
+ refcount_inc(&rt->refcnt);
}
static __inline__ void ipxrtr_put(struct ipx_route *rt)
{
- if (atomic_dec_and_test(&rt->refcnt))
+ if (refcount_dec_and_test(&rt->refcnt))
kfree(rt);
}
#endif /* _NET_INET_IPX_H_ */
diff --git a/net/ipx/ipx_route.c b/net/ipx/ipx_route.c
index 3e2a32a..b5d9144 100644
--- a/net/ipx/ipx_route.c
+++ b/net/ipx/ipx_route.c
@@ -59,7 +59,7 @@ int ipxrtr_add_route(__be32 network, struct ipx_interface *intrfc,
if (!rt)
goto out;
- atomic_set(&rt->refcnt, 1);
+ refcount_set(&rt->refcnt, 1);
ipxrtr_hold(rt);
write_lock_bh(&ipx_routes_lock);
list_add(&rt->node, &ipx_routes);
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 17/18] net, netrom: convert nr_neigh.refcount from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (15 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 16/18] net, ipx: convert ipx_route.refcnt " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
2017-03-17 11:12 ` [PATCH 18/18] net, netrom: convert nr_node.refcount " Elena Reshetova
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/netrom.h | 7 ++++---
net/netrom/nr_route.c | 4 ++--
2 files changed, 6 insertions(+), 5 deletions(-)
diff --git a/include/net/netrom.h b/include/net/netrom.h
index 110350a..cecb4fd 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -11,6 +11,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <net/sock.h>
+#include <linux/refcount.h>
#define NR_NETWORK_LEN 15
#define NR_TRANSPORT_LEN 5
@@ -93,7 +94,7 @@ struct nr_neigh {
unsigned short count;
unsigned int number;
unsigned char failed;
- atomic_t refcount;
+ refcount_t refcount;
};
struct nr_route {
@@ -128,11 +129,11 @@ static __inline__ void nr_node_put(struct nr_node *nr_node)
}
#define nr_neigh_hold(__nr_neigh) \
- atomic_inc(&((__nr_neigh)->refcount))
+ refcount_inc(&((__nr_neigh)->refcount))
static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
{
- if (atomic_dec_and_test(&nr_neigh->refcount)) {
+ if (refcount_dec_and_test(&nr_neigh->refcount)) {
if (nr_neigh->ax25)
ax25_cb_put(nr_neigh->ax25);
kfree(nr_neigh->digipeat);
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index d72a4f1..6b72970 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -149,7 +149,7 @@ static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
nr_neigh->failed = 0;
- atomic_set(&nr_neigh->refcount, 1);
+ refcount_set(&nr_neigh->refcount, 1);
if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
nr_neigh->digipeat = kmemdup(ax25_digi,
@@ -431,7 +431,7 @@ static int __must_check nr_add_neigh(ax25_address *callsign,
nr_neigh->count = 0;
nr_neigh->number = nr_neigh_no++;
nr_neigh->failed = 0;
- atomic_set(&nr_neigh->refcount, 1);
+ refcount_set(&nr_neigh->refcount, 1);
if (ax25_digi != NULL && ax25_digi->ndigi > 0) {
nr_neigh->digipeat = kmemdup(ax25_digi, sizeof(*ax25_digi),
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread* [PATCH 18/18] net, netrom: convert nr_node.refcount from atomic_t to refcount_t
2017-03-17 11:12 [PATCH 00/18] net subsystem various refcounter conversions Elena Reshetova
` (16 preceding siblings ...)
2017-03-17 11:12 ` [PATCH 17/18] net, netrom: convert nr_neigh.refcount " Elena Reshetova
@ 2017-03-17 11:12 ` Elena Reshetova
17 siblings, 0 replies; 20+ messages in thread
From: Elena Reshetova @ 2017-03-17 11:12 UTC (permalink / raw)
To: netdev
Cc: linux-kernel, linux-decnet-user, davem, jmorris, kaber, yoshfuji,
kuznet, 3chas3, ralf, stephen, jchapman, jhs, bridge, linux-hams,
linux-x25, linux-bluetooth, marcel, johan.hedberg, peterz,
keescook, Elena Reshetova, Hans Liljestrand, David Windsor
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>
---
include/net/netrom.h | 6 +++---
net/netrom/nr_route.c | 2 +-
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/include/net/netrom.h b/include/net/netrom.h
index cecb4fd..443a4ff 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -110,7 +110,7 @@ struct nr_node {
unsigned char which;
unsigned char count;
struct nr_route routes[3];
- atomic_t refcount;
+ refcount_t refcount;
spinlock_t node_lock;
};
@@ -119,11 +119,11 @@ struct nr_node {
*********************************************************************/
#define nr_node_hold(__nr_node) \
- atomic_inc(&((__nr_node)->refcount))
+ refcount_inc(&((__nr_node)->refcount))
static __inline__ void nr_node_put(struct nr_node *nr_node)
{
- if (atomic_dec_and_test(&nr_node->refcount)) {
+ if (refcount_dec_and_test(&nr_node->refcount)) {
kfree(nr_node);
}
}
diff --git a/net/netrom/nr_route.c b/net/netrom/nr_route.c
index 6b72970..0c59354 100644
--- a/net/netrom/nr_route.c
+++ b/net/netrom/nr_route.c
@@ -184,7 +184,7 @@ static int __must_check nr_add_node(ax25_address *nr, const char *mnemonic,
nr_node->which = 0;
nr_node->count = 1;
- atomic_set(&nr_node->refcount, 1);
+ refcount_set(&nr_node->refcount, 1);
spin_lock_init(&nr_node->node_lock);
nr_node->routes[0].quality = quality;
--
2.7.4
^ permalink raw reply related [flat|nested] 20+ messages in thread