From f6a6fede28e3cc3f9e4669a12839b47011330d95 Mon Sep 17 00:00:00 2001 From: "Reshetova, Elena" Date: Tue, 4 Jul 2017 09:35:01 +0300 Subject: net, ipv4: convert cipso_v4_doi.refcount 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/cipso_ipv4.h | 3 ++- net/ipv4/cipso_ipv4.c | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/include/net/cipso_ipv4.h b/include/net/cipso_ipv4.h index a34b141..880adb2 100644 --- a/include/net/cipso_ipv4.h +++ b/include/net/cipso_ipv4.h @@ -41,6 +41,7 @@ #include #include #include +#include #include /* known doi values */ @@ -85,7 +86,7 @@ struct cipso_v4_doi { } map; u8 tags[CIPSO_V4_TAG_MAXCNT]; - atomic_t refcount; + refcount_t refcount; struct list_head list; struct rcu_head rcu; }; diff --git a/net/ipv4/cipso_ipv4.c b/net/ipv4/cipso_ipv4.c index c204477..c4c6e19 100644 --- a/net/ipv4/cipso_ipv4.c +++ b/net/ipv4/cipso_ipv4.c @@ -375,7 +375,7 @@ static struct cipso_v4_doi *cipso_v4_doi_search(u32 doi) struct cipso_v4_doi *iter; list_for_each_entry_rcu(iter, &cipso_v4_doi_list, list) - if (iter->doi == doi && atomic_read(&iter->refcount)) + if (iter->doi == doi && refcount_read(&iter->refcount)) return iter; return NULL; } @@ -429,7 +429,7 @@ int cipso_v4_doi_add(struct cipso_v4_doi *doi_def, } } - atomic_set(&doi_def->refcount, 1); + refcount_set(&doi_def->refcount, 1); spin_lock(&cipso_v4_doi_list_lock); if (cipso_v4_doi_search(doi_def->doi)) { @@ -533,7 +533,7 @@ int cipso_v4_doi_remove(u32 doi, struct netlbl_audit *audit_info) ret_val = -ENOENT; goto doi_remove_return; } - if (!atomic_dec_and_test(&doi_def->refcount)) { + if (!refcount_dec_and_test(&doi_def->refcount)) { spin_unlock(&cipso_v4_doi_list_lock); ret_val = -EBUSY; goto doi_remove_return; @@ -576,7 +576,7 @@ struct cipso_v4_doi *cipso_v4_doi_getdef(u32 doi) doi_def = cipso_v4_doi_search(doi); if (!doi_def) goto doi_getdef_return; - if (!atomic_inc_not_zero(&doi_def->refcount)) + if (!refcount_inc_not_zero(&doi_def->refcount)) doi_def = NULL; doi_getdef_return: @@ -597,7 +597,7 @@ void cipso_v4_doi_putdef(struct cipso_v4_doi *doi_def) if (!doi_def) return; - if (!atomic_dec_and_test(&doi_def->refcount)) + if (!refcount_dec_and_test(&doi_def->refcount)) return; spin_lock(&cipso_v4_doi_list_lock); list_del_rcu(&doi_def->list); @@ -630,7 +630,7 @@ int cipso_v4_doi_walk(u32 *skip_cnt, rcu_read_lock(); list_for_each_entry_rcu(iter_doi, &cipso_v4_doi_list, list) - if (atomic_read(&iter_doi->refcount) > 0) { + if (refcount_read(&iter_doi->refcount) > 0) { if (doi_cnt++ < *skip_cnt) continue; ret_val = callback(iter_doi, cb_arg); -- cgit v1.1