Commit 93714912 authored by Reshetova, Elena's avatar Reshetova, Elena Committed by David S. Miller

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: default avatarElena Reshetova <elena.reshetova@intel.com>
Signed-off-by: default avatarHans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: default avatarKees Cook <keescook@chromium.org>
Signed-off-by: default avatarDavid Windsor <dwindsor@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 78893664
...@@ -40,7 +40,7 @@ static in_cache_entry *in_cache_get(__be32 dst_ip, ...@@ -40,7 +40,7 @@ static in_cache_entry *in_cache_get(__be32 dst_ip,
entry = client->in_cache; entry = client->in_cache;
while (entry != NULL) { while (entry != NULL) {
if (entry->ctrl_info.in_dst_ip == dst_ip) { if (entry->ctrl_info.in_dst_ip == dst_ip) {
atomic_inc(&entry->use); refcount_inc(&entry->use);
read_unlock_bh(&client->ingress_lock); read_unlock_bh(&client->ingress_lock);
return entry; return entry;
} }
...@@ -61,7 +61,7 @@ static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip, ...@@ -61,7 +61,7 @@ static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip,
entry = client->in_cache; entry = client->in_cache;
while (entry != NULL) { while (entry != NULL) {
if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) { 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); read_unlock_bh(&client->ingress_lock);
return entry; return entry;
} }
...@@ -82,7 +82,7 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc, ...@@ -82,7 +82,7 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc,
entry = client->in_cache; entry = client->in_cache;
while (entry != NULL) { while (entry != NULL) {
if (entry->shortcut == vcc) { if (entry->shortcut == vcc) {
atomic_inc(&entry->use); refcount_inc(&entry->use);
read_unlock_bh(&client->ingress_lock); read_unlock_bh(&client->ingress_lock);
return entry; return entry;
} }
...@@ -105,7 +105,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip, ...@@ -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); 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"); dprintk("new_in_cache_entry: about to lock\n");
write_lock_bh(&client->ingress_lock); write_lock_bh(&client->ingress_lock);
entry->next = client->in_cache; entry->next = client->in_cache;
...@@ -121,7 +121,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip, ...@@ -121,7 +121,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip,
entry->count = 1; entry->count = 1;
entry->entry_state = INGRESS_INVALID; entry->entry_state = INGRESS_INVALID;
entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT; entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT;
atomic_inc(&entry->use); refcount_inc(&entry->use);
write_unlock_bh(&client->ingress_lock); write_unlock_bh(&client->ingress_lock);
dprintk("new_in_cache_entry: unlocked\n"); dprintk("new_in_cache_entry: unlocked\n");
...@@ -178,7 +178,7 @@ static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc) ...@@ -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) 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)); memset(entry, 0, sizeof(in_cache_entry));
kfree(entry); kfree(entry);
} }
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
#include <linux/atm.h> #include <linux/atm.h>
#include <linux/atmdev.h> #include <linux/atmdev.h>
#include <linux/atmmpc.h> #include <linux/atmmpc.h>
#include <linux/refcount.h>
struct mpoa_client; struct mpoa_client;
...@@ -25,7 +26,7 @@ typedef struct in_cache_entry { ...@@ -25,7 +26,7 @@ typedef struct in_cache_entry {
struct atm_vcc *shortcut; struct atm_vcc *shortcut;
uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN]; uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN];
struct in_ctrl_info ctrl_info; struct in_ctrl_info ctrl_info;
atomic_t use; refcount_t use;
} in_cache_entry; } in_cache_entry;
struct in_cache_ops{ struct in_cache_ops{
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment