From 8c9814b97002f61846ebf3048e8df5aae52f7828 Mon Sep 17 00:00:00 2001 From: "Reshetova, Elena" Date: Fri, 30 Jun 2017 13:08:05 +0300 Subject: net: convert unix_address.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 --- include/net/af_unix.h | 3 ++- net/unix/af_unix.c | 8 ++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/net/af_unix.h b/include/net/af_unix.h index fd60eccb59a6..3a385e4767f0 100644 --- a/include/net/af_unix.h +++ b/include/net/af_unix.h @@ -4,6 +4,7 @@ #include #include #include +#include #include void unix_inflight(struct user_struct *user, struct file *fp); @@ -21,7 +22,7 @@ extern spinlock_t unix_table_lock; extern struct hlist_head unix_socket_table[2 * UNIX_HASH_SIZE]; struct unix_address { - atomic_t refcnt; + refcount_t refcnt; int len; unsigned int hash; struct sockaddr_un name[0]; diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c index c88525403d2e..b9ee766054f6 100644 --- a/net/unix/af_unix.c +++ b/net/unix/af_unix.c @@ -212,7 +212,7 @@ EXPORT_SYMBOL_GPL(unix_peer_get); static inline void unix_release_addr(struct unix_address *addr) { - if (atomic_dec_and_test(&addr->refcnt)) + if (refcount_dec_and_test(&addr->refcnt)) kfree(addr); } @@ -864,7 +864,7 @@ static int unix_autobind(struct socket *sock) goto out; addr->name->sun_family = AF_UNIX; - atomic_set(&addr->refcnt, 1); + refcount_set(&addr->refcnt, 1); retry: addr->len = sprintf(addr->name->sun_path+1, "%05x", ordernum) + 1 + sizeof(short); @@ -1040,7 +1040,7 @@ static int unix_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len) memcpy(addr->name, sunaddr, addr_len); addr->len = addr_len; addr->hash = hash ^ sk->sk_type; - atomic_set(&addr->refcnt, 1); + refcount_set(&addr->refcnt, 1); if (sun_path[0]) { addr->hash = UNIX_HASH_SIZE; @@ -1335,7 +1335,7 @@ restart: /* copy address information from listening to new sock*/ if (otheru->addr) { - atomic_inc(&otheru->addr->refcnt); + refcount_inc(&otheru->addr->refcnt); newu->addr = otheru->addr; } if (otheru->path.dentry) { -- cgit