From 937149125448290c5d60da2816556409287750ea Mon Sep 17 00:00:00 2001 From: "Reshetova, Elena" Date: Tue, 4 Jul 2017 15:53:03 +0300 Subject: [PATCH] net, atm: convert in_cache_entry.use 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 --- 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 a89fdebeffda..05e89e9930d5 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 8e5f78cf0be1..38a4e7e67c0b 100644 --- a/net/atm/mpoa_caches.h +++ b/net/atm/mpoa_caches.h @@ -6,6 +6,7 @@ #include #include #include +#include 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{ -- GitLab