From: Mathieu Desnoyers Date: Tue, 19 Jan 2016 20:23:01 +0000 (-0500) Subject: Fix: handle reference count overflow X-Git-Tag: v0.8.9~1 X-Git-Url: https://git.liburcu.org/?p=urcu.git;a=commitdiff_plain;h=3a03e6f37ee999c96024b8b99ba875a688fa1fe9 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 --- 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,