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 <[email protected]> Signed-off-by: Hans Liljestrand <[email protected]> Signed-off-by: Kees Cook <[email protected]> Signed-off-by: David Windsor <[email protected]> --- ipc/util.c | 6 +++--- ipc/util.h | 3 ++- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/ipc/util.c b/ipc/util.c index 798cad1..24484a6 100644 --- a/ipc/util.c +++ b/ipc/util.c @@ -437,7 +437,7 @@ void *ipc_rcu_alloc(int size) struct ipc_rcu *out = ipc_alloc(sizeof(struct ipc_rcu) + size); if (unlikely(!out)) return NULL; - atomic_set(&out->refcount, 1); + refcount_set(&out->refcount, 1); return out + 1; } @@ -445,14 +445,14 @@ int ipc_rcu_getref(void *ptr) { struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; - return atomic_inc_not_zero(&p->refcount); + return refcount_inc_not_zero(&p->refcount); } void ipc_rcu_putref(void *ptr, void (*func)(struct rcu_head *head)) { struct ipc_rcu *p = ((struct ipc_rcu *)ptr) - 1; - if (!atomic_dec_and_test(&p->refcount)) + if (!refcount_dec_and_test(&p->refcount)) return; call_rcu(&p->rcu, func); diff --git a/ipc/util.h b/ipc/util.h index 51f7ca5..274ec9b 100644 --- a/ipc/util.h +++ b/ipc/util.h @@ -12,6 +12,7 @@ #include <linux/unistd.h> #include <linux/err.h> +#include <linux/refcount.h> #define SEQ_MULTIPLIER (IPCMNI) @@ -49,7 +50,7 @@ static inline void shm_exit_ns(struct ipc_namespace *ns) { } struct ipc_rcu { struct rcu_head rcu; - atomic_t refcount; + refcount_t refcount; } ____cacheline_aligned_in_smp; #define ipc_rcu_to_struct(p) ((void *)(p+1)) -- 2.7.4

