diff options
author | Reshetova, Elena <elena.reshetova@intel.com> | 2017-07-04 08:53:03 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-07-04 17:35:16 -0400 |
commit | 937149125448290c5d60da2816556409287750ea (patch) | |
tree | 690fad95131beb68ac8b3561e4485ae09f42487f /net/atm | |
parent | 788936641ac8bc92c531f09b79bf44775fac1350 (diff) |
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 <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>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/atm')
-rw-r--r-- | net/atm/mpoa_caches.c | 12 | ||||
-rw-r--r-- | 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, | |||
40 | entry = client->in_cache; | 40 | entry = client->in_cache; |
41 | while (entry != NULL) { | 41 | while (entry != NULL) { |
42 | if (entry->ctrl_info.in_dst_ip == dst_ip) { | 42 | if (entry->ctrl_info.in_dst_ip == dst_ip) { |
43 | atomic_inc(&entry->use); | 43 | refcount_inc(&entry->use); |
44 | read_unlock_bh(&client->ingress_lock); | 44 | read_unlock_bh(&client->ingress_lock); |
45 | return entry; | 45 | return entry; |
46 | } | 46 | } |
@@ -61,7 +61,7 @@ static in_cache_entry *in_cache_get_with_mask(__be32 dst_ip, | |||
61 | entry = client->in_cache; | 61 | entry = client->in_cache; |
62 | while (entry != NULL) { | 62 | while (entry != NULL) { |
63 | if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) { | 63 | if ((entry->ctrl_info.in_dst_ip & mask) == (dst_ip & mask)) { |
64 | atomic_inc(&entry->use); | 64 | refcount_inc(&entry->use); |
65 | read_unlock_bh(&client->ingress_lock); | 65 | read_unlock_bh(&client->ingress_lock); |
66 | return entry; | 66 | return entry; |
67 | } | 67 | } |
@@ -82,7 +82,7 @@ static in_cache_entry *in_cache_get_by_vcc(struct atm_vcc *vcc, | |||
82 | entry = client->in_cache; | 82 | entry = client->in_cache; |
83 | while (entry != NULL) { | 83 | while (entry != NULL) { |
84 | if (entry->shortcut == vcc) { | 84 | if (entry->shortcut == vcc) { |
85 | atomic_inc(&entry->use); | 85 | refcount_inc(&entry->use); |
86 | read_unlock_bh(&client->ingress_lock); | 86 | read_unlock_bh(&client->ingress_lock); |
87 | return entry; | 87 | return entry; |
88 | } | 88 | } |
@@ -105,7 +105,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip, | |||
105 | 105 | ||
106 | dprintk("adding an ingress entry, ip = %pI4\n", &dst_ip); | 106 | dprintk("adding an ingress entry, ip = %pI4\n", &dst_ip); |
107 | 107 | ||
108 | atomic_set(&entry->use, 1); | 108 | refcount_set(&entry->use, 1); |
109 | dprintk("new_in_cache_entry: about to lock\n"); | 109 | dprintk("new_in_cache_entry: about to lock\n"); |
110 | write_lock_bh(&client->ingress_lock); | 110 | write_lock_bh(&client->ingress_lock); |
111 | entry->next = client->in_cache; | 111 | entry->next = client->in_cache; |
@@ -121,7 +121,7 @@ static in_cache_entry *in_cache_add_entry(__be32 dst_ip, | |||
121 | entry->count = 1; | 121 | entry->count = 1; |
122 | entry->entry_state = INGRESS_INVALID; | 122 | entry->entry_state = INGRESS_INVALID; |
123 | entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT; | 123 | entry->ctrl_info.holding_time = HOLDING_TIME_DEFAULT; |
124 | atomic_inc(&entry->use); | 124 | refcount_inc(&entry->use); |
125 | 125 | ||
126 | write_unlock_bh(&client->ingress_lock); | 126 | write_unlock_bh(&client->ingress_lock); |
127 | dprintk("new_in_cache_entry: unlocked\n"); | 127 | dprintk("new_in_cache_entry: unlocked\n"); |
@@ -178,7 +178,7 @@ static int cache_hit(in_cache_entry *entry, struct mpoa_client *mpc) | |||
178 | 178 | ||
179 | static void in_cache_put(in_cache_entry *entry) | 179 | static void in_cache_put(in_cache_entry *entry) |
180 | { | 180 | { |
181 | if (atomic_dec_and_test(&entry->use)) { | 181 | if (refcount_dec_and_test(&entry->use)) { |
182 | memset(entry, 0, sizeof(in_cache_entry)); | 182 | memset(entry, 0, sizeof(in_cache_entry)); |
183 | kfree(entry); | 183 | kfree(entry); |
184 | } | 184 | } |
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 @@ | |||
6 | #include <linux/atm.h> | 6 | #include <linux/atm.h> |
7 | #include <linux/atmdev.h> | 7 | #include <linux/atmdev.h> |
8 | #include <linux/atmmpc.h> | 8 | #include <linux/atmmpc.h> |
9 | #include <linux/refcount.h> | ||
9 | 10 | ||
10 | struct mpoa_client; | 11 | struct mpoa_client; |
11 | 12 | ||
@@ -25,7 +26,7 @@ typedef struct in_cache_entry { | |||
25 | struct atm_vcc *shortcut; | 26 | struct atm_vcc *shortcut; |
26 | uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN]; | 27 | uint8_t MPS_ctrl_ATM_addr[ATM_ESA_LEN]; |
27 | struct in_ctrl_info ctrl_info; | 28 | struct in_ctrl_info ctrl_info; |
28 | atomic_t use; | 29 | refcount_t use; |
29 | } in_cache_entry; | 30 | } in_cache_entry; |
30 | 31 | ||
31 | struct in_cache_ops{ | 32 | struct in_cache_ops{ |