From 3a03e6f37ee999c96024b8b99ba875a688fa1fe9 Mon Sep 17 00:00:00 2001 From: Mathieu Desnoyers Date: Tue, 19 Jan 2016 15:23:01 -0500 Subject: [PATCH] Fix: handle reference count overflow The urcu refcounting API features a look and feel similar to the Linux kernel reference counting API, which has been the subject of CVE-2016-0728 (use-after-free). Therefore, improve the urcu refcounting API by dealing with reference counting overflow. For urcu_ref_get(), handle this by comparing the prior value with LONG_MAX before updating it with a cmpxchg. When an overflow would occur, trigger a abort() rather than allowing the overflow (which is a use-after-free security concern). Signed-off-by: Mathieu Desnoyers --- urcu/ref.h | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/urcu/ref.h b/urcu/ref.h index a422a99..f2de26a 100644 --- a/urcu/ref.h +++ b/urcu/ref.h @@ -15,6 +15,8 @@ */ #include +#include +#include #include struct urcu_ref { @@ -33,7 +35,20 @@ static inline void urcu_ref_init(struct urcu_ref *ref) static inline void urcu_ref_get(struct urcu_ref *ref) { - uatomic_add(&ref->refcount, 1); + long old, _new, res; + + old = uatomic_read(&ref->refcount); + for (;;) { + if (old == LONG_MAX) { + abort(); + } + _new = old + 1; + res = uatomic_cmpxchg(&ref->refcount, old, _new); + if (res == old) { + return; + } + old = res; + } } static inline void urcu_ref_put(struct urcu_ref *ref, -- 2.34.1