diff options
author | Elena Reshetova <elena.reshetova@intel.com> | 2017-10-20 03:23:45 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2017-10-21 21:22:39 -0400 |
commit | 28206cdb3bc079a97d24c33b4427395f9e406fad (patch) | |
tree | ccfef81625bbe98a5632d1ef314b7deb7f9185bb | |
parent | 8676d76f087f9b2499f056aa0c5d857cffde6806 (diff) |
drivers, net: convert masces_tx_sa.refcnt from atomic_t to refcount_t
atomic_t variables are currently used to implement reference
counters with the following properties:
- counter is initialized to 1 using atomic_set()
- a resource is freed upon counter reaching zero
- once counter reaches zero, its further
increments aren't allowed
- counter schema uses basic atomic operations
(set, inc, inc_not_zero, dec_and_test, etc.)
Such atomic variables should be converted to a newly provided
refcount_t type and API that prevents accidental counter overflows
and underflows. This is important since overflows and underflows
can lead to use-after-free situation and be exploitable.
The variable masces_tx_sa.refcnt is used as pure reference counter.
Convert it to refcount_t and fix up the operations.
Suggested-by: Kees Cook <keescook@chromium.org>
Reviewed-by: David Windsor <dwindsor@gmail.com>
Reviewed-by: Hans Liljestrand <ishkamiel@gmail.com>
Signed-off-by: Elena Reshetova <elena.reshetova@intel.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/macsec.c | 8 |
1 files changed, 4 insertions, 4 deletions
diff --git a/drivers/net/macsec.c b/drivers/net/macsec.c index e0aeb51a5dab..8948b6adc0c5 100644 --- a/drivers/net/macsec.c +++ b/drivers/net/macsec.c | |||
@@ -188,7 +188,7 @@ struct macsec_tx_sa { | |||
188 | struct macsec_key key; | 188 | struct macsec_key key; |
189 | spinlock_t lock; | 189 | spinlock_t lock; |
190 | u32 next_pn; | 190 | u32 next_pn; |
191 | atomic_t refcnt; | 191 | refcount_t refcnt; |
192 | bool active; | 192 | bool active; |
193 | struct macsec_tx_sa_stats __percpu *stats; | 193 | struct macsec_tx_sa_stats __percpu *stats; |
194 | struct rcu_head rcu; | 194 | struct rcu_head rcu; |
@@ -362,7 +362,7 @@ static struct macsec_tx_sa *macsec_txsa_get(struct macsec_tx_sa __rcu *ptr) | |||
362 | if (!sa || !sa->active) | 362 | if (!sa || !sa->active) |
363 | return NULL; | 363 | return NULL; |
364 | 364 | ||
365 | if (!atomic_inc_not_zero(&sa->refcnt)) | 365 | if (!refcount_inc_not_zero(&sa->refcnt)) |
366 | return NULL; | 366 | return NULL; |
367 | 367 | ||
368 | return sa; | 368 | return sa; |
@@ -379,7 +379,7 @@ static void free_txsa(struct rcu_head *head) | |||
379 | 379 | ||
380 | static void macsec_txsa_put(struct macsec_tx_sa *sa) | 380 | static void macsec_txsa_put(struct macsec_tx_sa *sa) |
381 | { | 381 | { |
382 | if (atomic_dec_and_test(&sa->refcnt)) | 382 | if (refcount_dec_and_test(&sa->refcnt)) |
383 | call_rcu(&sa->rcu, free_txsa); | 383 | call_rcu(&sa->rcu, free_txsa); |
384 | } | 384 | } |
385 | 385 | ||
@@ -1437,7 +1437,7 @@ static int init_tx_sa(struct macsec_tx_sa *tx_sa, char *sak, int key_len, | |||
1437 | } | 1437 | } |
1438 | 1438 | ||
1439 | tx_sa->active = false; | 1439 | tx_sa->active = false; |
1440 | atomic_set(&tx_sa->refcnt, 1); | 1440 | refcount_set(&tx_sa->refcnt, 1); |
1441 | spin_lock_init(&tx_sa->lock); | 1441 | spin_lock_init(&tx_sa->lock); |
1442 | 1442 | ||
1443 | return 0; | 1443 | return 0; |