Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1680956 > unrolled thread

[PATCH 00/36] v2 net subsystem misc refcounter conversions

Started byElena Reshetova <elena.reshetova@intel.com>
First post2017-07-04 15:00 +0200
Last post2017-07-05 11:10 +0200
Articles 17 — 3 participants

Back to article view | Back to linux.kernel


Contents

  [PATCH 00/36] v2 net subsystem misc refcounter conversions Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:00 +0200
    [PATCH 29/36] net, sctp: convert sctp_auth_bytes.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:00 +0200
    [PATCH 26/36] net, xfrm: convert xfrm_state.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 04/36] net, vxlan: convert vxlan_sock.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 16/36] net, netrom: convert nr_neigh.refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 11/36] net, calipso: convert calipso_doi.refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 12/36] net, sched: convert Qdisc.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 05/36] net, decnet: convert dn_fib_info.fib_clntref from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 01/36] net, llc: convert llc_sap.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 32/36] net, sctp: convert sctp_transport.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 22/36] net, rds: convert rds_mr.r_refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 35/36] net, ax25: convert ax25_route.refcount from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 07/36] net, atm: convert lec_arp_table.usage from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 14/36] net, ipx: convert ipx_interface.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    [PATCH 31/36] net, sctp: convert sctp_chunk.refcnt from atomic_t to refcount_t Elena Reshetova <elena.reshetova@intel.com> - 2017-07-04 15:10 +0200
    Re: [PATCH 00/36] v2 net subsystem misc refcounter conversions David Miller <davem@davemloft.net> - 2017-07-05 00:10 +0200
      RE: [PATCH 00/36] v2 net subsystem misc refcounter conversions "Reshetova, Elena" <elena.reshetova@intel.com> - 2017-07-05 11:10 +0200

#1680956 — [PATCH 00/36] v2 net subsystem misc refcounter conversions

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:00 +0200
Subject[PATCH 00/36] v2 net subsystem misc refcounter conversions
Message-ID<tZvAS-8l6-9@gated-at.bofh.it>
Changes in v2:
 * rebase on top of net-next
 * currently by default refcount_t = atomic_t (*) and uses all 
   atomic standard operations unless CONFIG_REFCOUNT_FULL is enabled.
   This is a compromise for the systems that are critical on
   performance (such as net) and cannot accept even slight delay
   on the refcounter operations.

This series, for various misc network components, replaces atomic_t reference
counters with the new refcount_t type and API (see include/linux/refcount.h).
By doing this we prevent intentional or accidental
underflows or overflows that can led to use-after-free vulnerabilities.
These are the last networking-related conversions with the exception of
network drivers (to be send separately).

Please excuse the long patch set, but seems like breaking it up
won't save that much on CC list and most of the changes are
trivial.

The patches are fully independent and can be cherry-picked separately.
In order to try with refcount functionality enabled in run-time,
CONFIG_REFCOUNT_FULL must be enabled.

NOTE: automatic kernel builder for some reason doesn't like all my
network branches and regularly times out the builds on these branches.
Suggestion for "waiting a day for a good coverage" doesn't work, as
we have seen with generic network conversions. So please wait for the
full report from kernel test rebot before merging further up.
This has been compile-tested in 116 configs, but 71 timed out (including
all s390-related configs again). I am trying to see if they can fix
build coverage for me in meanwhile.

* The respective change is currently merged into -next as
  "locking/refcount: Create unchecked atomic_t implementation".

Elena Reshetova (36):
  net, llc: convert llc_sap.refcnt from atomic_t to refcount_t
  net, l2tp: convert l2tp_tunnel.ref_count from atomic_t to refcount_t
  net, l2tp: convert l2tp_session.ref_count from atomic_t to refcount_t
  net, vxlan: convert vxlan_sock.refcnt from atomic_t to refcount_t
  net, decnet: convert dn_fib_info.fib_clntref from atomic_t to
    refcount_t
  net, atm: convert atm_dev.refcnt from atomic_t to refcount_t
  net, atm: convert lec_arp_table.usage from atomic_t to refcount_t
  net, atm: convert in_cache_entry.use from atomic_t to refcount_t
  net, atm: convert eg_cache_entry.use from atomic_t to refcount_t
  net, bridge: convert net_bridge_vlan.refcnt from atomic_t to
    refcount_t
  net, calipso: convert calipso_doi.refcount from atomic_t to refcount_t
  net, sched: convert Qdisc.refcnt from atomic_t to refcount_t
  net, lapb: convert lapb_cb.refcnt from atomic_t to refcount_t
  net, ipx: convert ipx_interface.refcnt from atomic_t to refcount_t
  net, ipx: convert ipx_route.refcnt from atomic_t to refcount_t
  net, netrom: convert nr_neigh.refcount from atomic_t to refcount_t
  net, netrom: convert nr_node.refcount from atomic_t to refcount_t
  net, sunrpc: convert gss_cl_ctx.count from atomic_t to refcount_t
  net, sunrpc: convert gss_upcall_msg.count from atomic_t to refcount_t
  net, rds: convert rds_ib_device.refcount from atomic_t to refcount_t
  net, rds: convert rds_incoming.i_refcount from atomic_t to refcount_t
  net, rds: convert rds_mr.r_refcount from atomic_t to refcount_t
  net, rds: convert rds_message.m_refcount from atomic_t to refcount_t
  net, x25: convert x25_route.refcnt from atomic_t to refcount_t
  net, x25: convert x25_neigh.refcnt from atomic_t to refcount_t
  net, xfrm: convert xfrm_state.refcnt from atomic_t to refcount_t
  net, xfrm: convert xfrm_policy.refcnt from atomic_t to refcount_t
  net, xfrm: convert sec_path.refcnt from atomic_t to refcount_t
  net, sctp: convert sctp_auth_bytes.refcnt from atomic_t to refcount_t
  net, sctp: convert sctp_datamsg.refcnt from atomic_t to refcount_t
  net, sctp: convert sctp_chunk.refcnt from atomic_t to refcount_t
  net, sctp: convert sctp_transport.refcnt from atomic_t to refcount_t
  net, sctp: convert sctp_ep_common.refcnt from atomic_t to refcount_t
  net, ax25: convert ax25_uid_assoc.refcount from atomic_t to refcount_t
  net, ax25: convert ax25_route.refcount from atomic_t to refcount_t
  net, ax25: convert ax25_cb.refcount from atomic_t to refcount_t

 drivers/net/vxlan.c             | 10 +++++-----
 include/linux/atmdev.h          |  7 ++++---
 include/linux/sunrpc/auth_gss.h |  3 ++-
 include/net/ax25.h              | 20 ++++++++++----------
 include/net/calipso.h           |  4 ++--
 include/net/dn_fib.h            |  5 +++--
 include/net/ipx.h               | 13 +++++++------
 include/net/lapb.h              |  3 ++-
 include/net/llc.h               |  6 +++---
 include/net/netrom.h            | 13 +++++++------
 include/net/sch_generic.h       |  3 ++-
 include/net/sctp/auth.h         |  5 +++--
 include/net/sctp/structs.h      |  8 ++++----
 include/net/vxlan.h             |  2 +-
 include/net/x25.h               | 13 +++++++------
 include/net/xfrm.h              | 21 +++++++++++----------
 net/atm/lec.c                   |  6 +++---
 net/atm/lec_arpc.h              |  2 +-
 net/atm/mpoa_caches.c           | 26 +++++++++++++-------------
 net/atm/mpoa_caches.h           |  5 +++--
 net/atm/proc.c                  |  2 +-
 net/atm/resources.c             |  2 +-
 net/ax25/af_ax25.c              |  2 +-
 net/ax25/ax25_route.c           |  2 +-
 net/ax25/ax25_uid.c             |  2 +-
 net/bridge/br_private.h         |  3 ++-
 net/bridge/br_vlan.c            |  8 ++++----
 net/decnet/dn_fib.c             |  6 +++---
 net/ipv6/calipso.c              | 12 ++++++------
 net/ipx/af_ipx.c                |  6 +++---
 net/ipx/ipx_proc.c              |  2 +-
 net/ipx/ipx_route.c             |  2 +-
 net/key/af_key.c                |  2 +-
 net/l2tp/l2tp_core.c            | 16 ++++++++--------
 net/l2tp/l2tp_core.h            | 13 +++++++------
 net/l2tp/l2tp_debugfs.c         |  4 ++--
 net/l2tp/l2tp_ppp.c             |  2 +-
 net/lapb/lapb_iface.c           |  6 +++---
 net/llc/llc_core.c              |  2 +-
 net/netrom/nr_route.c           |  6 +++---
 net/rds/ib.c                    | 12 ++++++------
 net/rds/ib.h                    |  2 +-
 net/rds/ib_rdma.c               |  4 ++--
 net/rds/message.c               | 12 ++++++------
 net/rds/rdma.c                  | 10 +++++-----
 net/rds/rds.h                   |  9 +++++----
 net/rds/recv.c                  | 12 ++++++------
 net/sched/sch_api.c             |  8 ++++----
 net/sched/sch_generic.c         |  8 ++++----
 net/sctp/associola.c            |  6 +++---
 net/sctp/auth.c                 |  4 ++--
 net/sctp/chunk.c                |  6 +++---
 net/sctp/endpointola.c          |  6 +++---
 net/sctp/sm_make_chunk.c        |  6 +++---
 net/sctp/transport.c            |  8 ++++----
 net/sunrpc/auth_gss/auth_gss.c  | 28 ++++++++++++++--------------
 net/x25/x25_link.c              |  2 +-
 net/x25/x25_route.c             |  2 +-
 net/xfrm/xfrm_input.c           |  4 ++--
 net/xfrm/xfrm_policy.c          |  4 ++--
 net/xfrm/xfrm_state.c           |  4 ++--
 61 files changed, 223 insertions(+), 209 deletions(-)

-- 
2.7.4

[toc] | [next] | [standalone]


#1680957 — [PATCH 29/36] net, sctp: convert sctp_auth_bytes.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:00 +0200
Subject[PATCH 29/36] net, sctp: convert sctp_auth_bytes.refcnt from atomic_t to refcount_t
Message-ID<tZvAV-8l6-67@gated-at.bofh.it>
In reply to#1680956
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/sctp/auth.h | 5 +++--
 net/sctp/auth.c         | 4 ++--
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/net/sctp/auth.h b/include/net/sctp/auth.h
index 171244b..e5c57d0 100644
--- a/include/net/sctp/auth.h
+++ b/include/net/sctp/auth.h
@@ -31,6 +31,7 @@
 #define __sctp_auth_h__
 
 #include <linux/list.h>
+#include <linux/refcount.h>
 
 struct sctp_endpoint;
 struct sctp_association;
@@ -53,7 +54,7 @@ struct sctp_hmac {
  * over SCTP-AUTH
  */
 struct sctp_auth_bytes {
-	atomic_t refcnt;
+	refcount_t refcnt;
 	__u32 len;
 	__u8  data[];
 };
@@ -76,7 +77,7 @@ static inline void sctp_auth_key_hold(struct sctp_auth_bytes *key)
 	if (!key)
 		return;
 
-	atomic_inc(&key->refcnt);
+	refcount_inc(&key->refcnt);
 }
 
 void sctp_auth_key_put(struct sctp_auth_bytes *key);
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 8ffa598..e001b01 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -63,7 +63,7 @@ void sctp_auth_key_put(struct sctp_auth_bytes *key)
 	if (!key)
 		return;
 
-	if (atomic_dec_and_test(&key->refcnt)) {
+	if (refcount_dec_and_test(&key->refcnt)) {
 		kzfree(key);
 		SCTP_DBG_OBJCNT_DEC(keys);
 	}
@@ -84,7 +84,7 @@ static struct sctp_auth_bytes *sctp_auth_create_key(__u32 key_len, gfp_t gfp)
 		return NULL;
 
 	key->len = key_len;
-	atomic_set(&key->refcnt, 1);
+	refcount_set(&key->refcnt, 1);
 	SCTP_DBG_OBJCNT_INC(keys);
 
 	return key;
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1680958 — [PATCH 26/36] net, xfrm: convert xfrm_state.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 26/36] net, xfrm: convert xfrm_state.refcnt from atomic_t to refcount_t
Message-ID<tZvKy-bO-1@gated-at.bofh.it>
In reply to#1680956
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/xfrm.h    | 9 +++++----
 net/xfrm/xfrm_state.c | 4 ++--
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/include/net/xfrm.h b/include/net/xfrm.h
index 01fa357..f5272a2 100644
--- a/include/net/xfrm.h
+++ b/include/net/xfrm.h
@@ -13,6 +13,7 @@
 #include <linux/mutex.h>
 #include <linux/audit.h>
 #include <linux/slab.h>
+#include <linux/refcount.h>
 
 #include <net/sock.h>
 #include <net/dst.h>
@@ -137,7 +138,7 @@ struct xfrm_state {
 	struct hlist_node	bysrc;
 	struct hlist_node	byspi;
 
-	atomic_t		refcnt;
+	refcount_t		refcnt;
 	spinlock_t		lock;
 
 	struct xfrm_id		id;
@@ -837,18 +838,18 @@ void __xfrm_state_destroy(struct xfrm_state *);
 
 static inline void __xfrm_state_put(struct xfrm_state *x)
 {
-	atomic_dec(&x->refcnt);
+	refcount_dec(&x->refcnt);
 }
 
 static inline void xfrm_state_put(struct xfrm_state *x)
 {
-	if (atomic_dec_and_test(&x->refcnt))
+	if (refcount_dec_and_test(&x->refcnt))
 		__xfrm_state_destroy(x);
 }
 
 static inline void xfrm_state_hold(struct xfrm_state *x)
 {
-	atomic_inc(&x->refcnt);
+	refcount_inc(&x->refcnt);
 }
 
 static inline bool addr_match(const void *token1, const void *token2,
diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c
index 4a28f66..6c0956d 100644
--- a/net/xfrm/xfrm_state.c
+++ b/net/xfrm/xfrm_state.c
@@ -48,7 +48,7 @@ static HLIST_HEAD(xfrm_state_gc_list);
 
 static inline bool xfrm_state_hold_rcu(struct xfrm_state __rcu *x)
 {
-	return atomic_inc_not_zero(&x->refcnt);
+	return refcount_inc_not_zero(&x->refcnt);
 }
 
 static inline unsigned int xfrm_dst_hash(struct net *net,
@@ -558,7 +558,7 @@ struct xfrm_state *xfrm_state_alloc(struct net *net)
 
 	if (x) {
 		write_pnet(&x->xs_net, net);
-		atomic_set(&x->refcnt, 1);
+		refcount_set(&x->refcnt, 1);
 		atomic_set(&x->tunnel_users, 0);
 		INIT_LIST_HEAD(&x->km.all);
 		INIT_HLIST_NODE(&x->bydst);
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1680959 — [PATCH 04/36] net, vxlan: convert vxlan_sock.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 04/36] net, vxlan: convert vxlan_sock.refcnt from atomic_t to refcount_t
Message-ID<tZvKy-bO-3@gated-at.bofh.it>
In reply to#1680956
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 b04e103..96aa7e6 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -1034,11 +1034,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
 
@@ -1075,7 +1075,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);
@@ -2825,7 +2825,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);
@@ -2860,7 +2860,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->cfg.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 326e849..3f430e3 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

[toc] | [prev] | [next] | [standalone]


#1680960 — [PATCH 16/36] net, netrom: convert nr_neigh.refcount from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 16/36] net, netrom: convert nr_neigh.refcount from atomic_t to refcount_t
Message-ID<tZvKy-bO-9@gated-at.bofh.it>
In reply to#1680956
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

[toc] | [prev] | [next] | [standalone]


#1680961 — [PATCH 11/36] net, calipso: convert calipso_doi.refcount from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 11/36] net, calipso: convert calipso_doi.refcount from atomic_t to refcount_t
Message-ID<tZvKy-bO-7@gated-at.bofh.it>
In reply to#1680956
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 4406752..1323b96 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

[toc] | [prev] | [next] | [standalone]


#1680962 — [PATCH 12/36] net, sched: convert Qdisc.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 12/36] net, sched: convert Qdisc.refcnt from atomic_t to refcount_t
Message-ID<tZvKy-bO-11@gated-at.bofh.it>
In reply to#1680956
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 3688501..1c123e2 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -9,6 +9,7 @@
 #include <linux/percpu.h>
 #include <linux/dynamic_queue_limits.h>
 #include <linux/list.h>
+#include <linux/refcount.h>
 #include <net/gen_stats.h>
 #include <net/rtnetlink.h>
 
@@ -95,7 +96,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 43b94c7..bd24a55 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -839,7 +839,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);
@@ -850,7 +850,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)
@@ -1259,7 +1259,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)
@@ -1374,7 +1374,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 52a2c55..57ba406 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

[toc] | [prev] | [next] | [standalone]


#1680963 — [PATCH 05/36] net, decnet: convert dn_fib_info.fib_clntref from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 05/36] net, decnet: convert dn_fib_info.fib_clntref from atomic_t to refcount_t
Message-ID<tZvKy-bO-17@gated-at.bofh.it>
In reply to#1680956
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 f9058eb..f9f6fb3 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

[toc] | [prev] | [next] | [standalone]


#1680965 — [PATCH 01/36] net, llc: convert llc_sap.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 01/36] net, llc: convert llc_sap.refcnt from atomic_t to refcount_t
Message-ID<tZvKz-bO-27@gated-at.bofh.it>
In reply to#1680956
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

[toc] | [prev] | [next] | [standalone]


#1680966 — [PATCH 32/36] net, sctp: convert sctp_transport.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 32/36] net, sctp: convert sctp_transport.refcnt from atomic_t to refcount_t
Message-ID<tZvKz-bO-25@gated-at.bofh.it>
In reply to#1680956
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/sctp/structs.h | 2 +-
 net/sctp/transport.c       | 8 ++++----
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 0dfc5c1..6a0d372 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -735,7 +735,7 @@ struct sctp_transport {
 	struct rhlist_head node;
 
 	/* Reference counting. */
-	atomic_t refcnt;
+	refcount_t refcnt;
 		/* RTO-Pending : A flag used to track if one of the DATA
 		 *		chunks sent to this address is currently being
 		 *		used to compute a RTT. If this flag is 0,
diff --git a/net/sctp/transport.c b/net/sctp/transport.c
index 7cdd6bc..80a97c8 100644
--- a/net/sctp/transport.c
+++ b/net/sctp/transport.c
@@ -99,7 +99,7 @@ static struct sctp_transport *sctp_transport_init(struct net *net,
 	/* Initialize the 64-bit random nonce sent with heartbeat. */
 	get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));
 
-	atomic_set(&peer->refcnt, 1);
+	refcount_set(&peer->refcnt, 1);
 
 	return peer;
 }
@@ -172,7 +172,7 @@ static void sctp_transport_destroy_rcu(struct rcu_head *head)
  */
 static void sctp_transport_destroy(struct sctp_transport *transport)
 {
-	if (unlikely(atomic_read(&transport->refcnt))) {
+	if (unlikely(refcount_read(&transport->refcnt))) {
 		WARN(1, "Attempt to destroy undead transport %p!\n", transport);
 		return;
 	}
@@ -311,7 +311,7 @@ void sctp_transport_route(struct sctp_transport *transport,
 /* Hold a reference to a transport.  */
 int sctp_transport_hold(struct sctp_transport *transport)
 {
-	return atomic_add_unless(&transport->refcnt, 1, 0);
+	return refcount_inc_not_zero(&transport->refcnt);
 }
 
 /* Release a reference to a transport and clean up
@@ -319,7 +319,7 @@ int sctp_transport_hold(struct sctp_transport *transport)
  */
 void sctp_transport_put(struct sctp_transport *transport)
 {
-	if (atomic_dec_and_test(&transport->refcnt))
+	if (refcount_dec_and_test(&transport->refcnt))
 		sctp_transport_destroy(transport);
 }
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1680969 — [PATCH 22/36] net, rds: convert rds_mr.r_refcount from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 22/36] net, rds: convert rds_mr.r_refcount from atomic_t to refcount_t
Message-ID<tZvKz-bO-39@gated-at.bofh.it>
In reply to#1680956
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/rds/rdma.c | 10 +++++-----
 net/rds/rds.h  |  4 ++--
 2 files changed, 7 insertions(+), 7 deletions(-)

diff --git a/net/rds/rdma.c b/net/rds/rdma.c
index f06fac4..8886f15 100644
--- a/net/rds/rdma.c
+++ b/net/rds/rdma.c
@@ -84,7 +84,7 @@ static struct rds_mr *rds_mr_tree_walk(struct rb_root *root, u64 key,
 	if (insert) {
 		rb_link_node(&insert->r_rb_node, parent, p);
 		rb_insert_color(&insert->r_rb_node, root);
-		atomic_inc(&insert->r_refcount);
+		refcount_inc(&insert->r_refcount);
 	}
 	return NULL;
 }
@@ -99,7 +99,7 @@ static void rds_destroy_mr(struct rds_mr *mr)
 	unsigned long flags;
 
 	rdsdebug("RDS: destroy mr key is %x refcnt %u\n",
-			mr->r_key, atomic_read(&mr->r_refcount));
+			mr->r_key, refcount_read(&mr->r_refcount));
 
 	if (test_and_set_bit(RDS_MR_DEAD, &mr->r_state))
 		return;
@@ -223,7 +223,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 		goto out;
 	}
 
-	atomic_set(&mr->r_refcount, 1);
+	refcount_set(&mr->r_refcount, 1);
 	RB_CLEAR_NODE(&mr->r_rb_node);
 	mr->r_trans = rs->rs_transport;
 	mr->r_sock = rs;
@@ -307,7 +307,7 @@ static int __rds_rdma_map(struct rds_sock *rs, struct rds_get_mr_args *args,
 
 	rdsdebug("RDS: get_mr key is %x\n", mr->r_key);
 	if (mr_ret) {
-		atomic_inc(&mr->r_refcount);
+		refcount_inc(&mr->r_refcount);
 		*mr_ret = mr;
 	}
 
@@ -756,7 +756,7 @@ int rds_cmsg_rdma_dest(struct rds_sock *rs, struct rds_message *rm,
 	if (!mr)
 		err = -EINVAL;	/* invalid r_key */
 	else
-		atomic_inc(&mr->r_refcount);
+		refcount_inc(&mr->r_refcount);
 	spin_unlock_irqrestore(&rs->rs_rdma_lock, flags);
 
 	if (mr) {
diff --git a/net/rds/rds.h b/net/rds/rds.h
index 35ceaa2..ea72d6e 100644
--- a/net/rds/rds.h
+++ b/net/rds/rds.h
@@ -277,7 +277,7 @@ struct rds_incoming {
 
 struct rds_mr {
 	struct rb_node		r_rb_node;
-	atomic_t		r_refcount;
+	refcount_t		r_refcount;
 	u32			r_key;
 
 	/* A copy of the creation flags */
@@ -857,7 +857,7 @@ int rds_cmsg_atomic(struct rds_sock *rs, struct rds_message *rm,
 void __rds_put_mr_final(struct rds_mr *mr);
 static inline void rds_mr_put(struct rds_mr *mr)
 {
-	if (atomic_dec_and_test(&mr->r_refcount))
+	if (refcount_dec_and_test(&mr->r_refcount))
 		__rds_put_mr_final(mr);
 }
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1680971 — [PATCH 35/36] net, ax25: convert ax25_route.refcount from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 35/36] net, ax25: convert ax25_route.refcount from atomic_t to refcount_t
Message-ID<tZvKz-bO-47@gated-at.bofh.it>
In reply to#1680956
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/ax25.h    | 6 +++---
 net/ax25/ax25_route.c | 2 +-
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/net/ax25.h b/include/net/ax25.h
index edd82f0..e3467ba 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -185,7 +185,7 @@ typedef struct {
 
 typedef struct ax25_route {
 	struct ax25_route	*next;
-	atomic_t		refcount;
+	refcount_t		refcount;
 	ax25_address		callsign;
 	struct net_device	*dev;
 	ax25_digi		*digipeat;
@@ -194,14 +194,14 @@ typedef struct ax25_route {
 
 static inline void ax25_hold_route(ax25_route *ax25_rt)
 {
-	atomic_inc(&ax25_rt->refcount);
+	refcount_inc(&ax25_rt->refcount);
 }
 
 void __ax25_put_route(ax25_route *ax25_rt);
 
 static inline void ax25_put_route(ax25_route *ax25_rt)
 {
-	if (atomic_dec_and_test(&ax25_rt->refcount))
+	if (refcount_dec_and_test(&ax25_rt->refcount))
 		__ax25_put_route(ax25_rt);
 }
 
diff --git a/net/ax25/ax25_route.c b/net/ax25/ax25_route.c
index e1fda27..0446b89 100644
--- a/net/ax25/ax25_route.c
+++ b/net/ax25/ax25_route.c
@@ -114,7 +114,7 @@ static int __must_check ax25_rt_add(struct ax25_routes_struct *route)
 		return -ENOMEM;
 	}
 
-	atomic_set(&ax25_rt->refcount, 1);
+	refcount_set(&ax25_rt->refcount, 1);
 	ax25_rt->callsign     = route->dest_addr;
 	ax25_rt->dev          = ax25_dev->dev;
 	ax25_rt->digipeat     = NULL;
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1680973 — [PATCH 07/36] net, atm: convert lec_arp_table.usage from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 07/36] net, atm: convert lec_arp_table.usage from atomic_t to refcount_t
Message-ID<tZvKA-bO-53@gated-at.bofh.it>
In reply to#1680956
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 7554571..093fe87 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

[toc] | [prev] | [next] | [standalone]


#1680974 — [PATCH 14/36] net, ipx: convert ipx_interface.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 14/36] net, ipx: convert ipx_interface.refcnt from atomic_t to refcount_t
Message-ID<tZvKA-bO-51@gated-at.bofh.it>
In reply to#1680956
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 fa31ef2..ac598ec 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

[toc] | [prev] | [next] | [standalone]


#1680975 — [PATCH 31/36] net, sctp: convert sctp_chunk.refcnt from atomic_t to refcount_t

FromElena Reshetova <elena.reshetova@intel.com>
Date2017-07-04 15:10 +0200
Subject[PATCH 31/36] net, sctp: convert sctp_chunk.refcnt from atomic_t to refcount_t
Message-ID<tZvKA-bO-55@gated-at.bofh.it>
In reply to#1680956
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/sctp/structs.h | 2 +-
 net/sctp/sm_make_chunk.c   | 6 +++---
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index 4d7c855..0dfc5c1 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -524,7 +524,7 @@ int sctp_chunk_abandoned(struct sctp_chunk *);
 struct sctp_chunk {
 	struct list_head list;
 
-	atomic_t refcnt;
+	refcount_t refcnt;
 
 	/* How many times this chunk have been sent, for prsctp RTX policy */
 	int sent_count;
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 3af4dd0..4e16b02 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -1345,7 +1345,7 @@ struct sctp_chunk *sctp_chunkify(struct sk_buff *skb,
 	INIT_LIST_HEAD(&retval->transmitted_list);
 	INIT_LIST_HEAD(&retval->frag_list);
 	SCTP_DBG_OBJCNT_INC(chunk);
-	atomic_set(&retval->refcnt, 1);
+	refcount_set(&retval->refcnt, 1);
 
 nodata:
 	return retval;
@@ -1458,13 +1458,13 @@ void sctp_chunk_free(struct sctp_chunk *chunk)
 /* Grab a reference to the chunk. */
 void sctp_chunk_hold(struct sctp_chunk *ch)
 {
-	atomic_inc(&ch->refcnt);
+	refcount_inc(&ch->refcnt);
 }
 
 /* Release a reference to the chunk. */
 void sctp_chunk_put(struct sctp_chunk *ch)
 {
-	if (atomic_dec_and_test(&ch->refcnt))
+	if (refcount_dec_and_test(&ch->refcnt))
 		sctp_chunk_destroy(ch);
 }
 
-- 
2.7.4

[toc] | [prev] | [next] | [standalone]


#1681200

FromDavid Miller <davem@davemloft.net>
Date2017-07-05 00:10 +0200
Message-ID<tZEb7-5V4-5@gated-at.bofh.it>
In reply to#1680956
From: Elena Reshetova <elena.reshetova@intel.com>
Date: Tue,  4 Jul 2017 15:52:55 +0300

> Changes in v2:
>  * rebase on top of net-next
>  * currently by default refcount_t = atomic_t (*) and uses all 
>    atomic standard operations unless CONFIG_REFCOUNT_FULL is enabled.
>    This is a compromise for the systems that are critical on
>    performance (such as net) and cannot accept even slight delay
>    on the refcounter operations.
> 
> This series, for various misc network components, replaces atomic_t reference
> counters with the new refcount_t type and API (see include/linux/refcount.h).
> By doing this we prevent intentional or accidental
> underflows or overflows that can led to use-after-free vulnerabilities.
> These are the last networking-related conversions with the exception of
> network drivers (to be send separately).
> 
> Please excuse the long patch set, but seems like breaking it up
> won't save that much on CC list and most of the changes are
> trivial.
> 
> The patches are fully independent and can be cherry-picked separately.
> In order to try with refcount functionality enabled in run-time,
> CONFIG_REFCOUNT_FULL must be enabled.
> 
> NOTE: automatic kernel builder for some reason doesn't like all my
> network branches and regularly times out the builds on these branches.
> Suggestion for "waiting a day for a good coverage" doesn't work, as
> we have seen with generic network conversions. So please wait for the
> full report from kernel test rebot before merging further up.
> This has been compile-tested in 116 configs, but 71 timed out (including
> all s390-related configs again). I am trying to see if they can fix
> build coverage for me in meanwhile.
> 
> * The respective change is currently merged into -next as
>   "locking/refcount: Create unchecked atomic_t implementation".

Series applied, that's enough for this cycle, please.

[toc] | [prev] | [next] | [standalone]


#1681395

From"Reshetova, Elena" <elena.reshetova@intel.com>
Date2017-07-05 11:10 +0200
Message-ID<tZOtR-4hV-23@gated-at.bofh.it>
In reply to#1681200
> From: Elena Reshetova <elena.reshetova@intel.com>
> Date: Tue,  4 Jul 2017 15:52:55 +0300
> 
> > Changes in v2:
> >  * rebase on top of net-next
> >  * currently by default refcount_t = atomic_t (*) and uses all
> >    atomic standard operations unless CONFIG_REFCOUNT_FULL is enabled.
> >    This is a compromise for the systems that are critical on
> >    performance (such as net) and cannot accept even slight delay
> >    on the refcounter operations.
> >
> > This series, for various misc network components, replaces atomic_t reference
> > counters with the new refcount_t type and API (see include/linux/refcount.h).
> > By doing this we prevent intentional or accidental
> > underflows or overflows that can led to use-after-free vulnerabilities.
> > These are the last networking-related conversions with the exception of
> > network drivers (to be send separately).
> >
> > Please excuse the long patch set, but seems like breaking it up
> > won't save that much on CC list and most of the changes are
> > trivial.
> >
> > The patches are fully independent and can be cherry-picked separately.
> > In order to try with refcount functionality enabled in run-time,
> > CONFIG_REFCOUNT_FULL must be enabled.
> >
> > NOTE: automatic kernel builder for some reason doesn't like all my
> > network branches and regularly times out the builds on these branches.
> > Suggestion for "waiting a day for a good coverage" doesn't work, as
> > we have seen with generic network conversions. So please wait for the
> > full report from kernel test rebot before merging further up.
> > This has been compile-tested in 116 configs, but 71 timed out (including
> > all s390-related configs again). I am trying to see if they can fix
> > build coverage for me in meanwhile.
> >
> > * The respective change is currently merged into -next as
> >   "locking/refcount: Create unchecked atomic_t implementation".
> 
> Series applied, that's enough for this cycle, please.

Thank you very much David! I really appreciate you taking so many of these conversions in
one go! I will stop for now :) 

With regards to net, I only have networking drivers left (16 patches in total), but I can submit them in the
next round. Will go bug other subsystem maintainers next :) 

Best Regards,
Elena.

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web