From: Reshetova, Elena Date: Tue, 4 Jul 2017 12:53:27 +0000 (+0300) Subject: net, sctp: convert sctp_transport.refcnt from atomic_t to refcount_t X-Git-Tag: v4.13-rc1~157^2~7^2~4 X-Git-Url: https://git.kernel.dk/?a=commitdiff_plain;h=a4b2b58efd44db68358e1a6b71cf205c795d7ada;p=linux-block.git net, sctp: convert sctp_transport.refcnt from atomic_t to refcount_t refcount_t type and corresponding API should be used instead of atomic_t when the variable is used as a reference counter. This allows to avoid accidental refcounter overflows that might lead to use-after-free situations. Signed-off-by: Elena Reshetova Signed-off-by: Hans Liljestrand Signed-off-by: Kees Cook Signed-off-by: David Windsor Signed-off-by: David S. Miller --- diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 0dfc5c14b696..6a0d37258506 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 7cdd6bcddbc5..80a97c8501a7 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); }