From: Ondřej Surý Date: Mon, 15 Jul 2019 08:20:16 +0000 (+0200) Subject: Restore DbC checks in isc_refcount API X-Git-Tag: v9.15.8~10^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=49976947abaaf693c3caf11f22c693777f6a3e4c;p=thirdparty%2Fbind9.git Restore DbC checks in isc_refcount API The isc_refcount API that provides reference counting lost DbC checks for overflows and underflows in the isc_refcount_{increment,decrement} functions. The commit restores the overflow check in the isc_refcount_increment and underflows check in the isc_refcount_decrement by checking for the previous value to not be on the boundary. --- diff --git a/lib/isc/include/isc/refcount.h b/lib/isc/include/isc/refcount.h index 4e7f4d439fa..0b9640ab022 100644 --- a/lib/isc/include/isc/refcount.h +++ b/lib/isc/include/isc/refcount.h @@ -52,15 +52,15 @@ typedef atomic_uint_fast32_t isc_refcount_t; * atomic_load_explicit() by casting to uint_fast32_t. */ -#define isc_refcount_current(target) \ - (uint_fast32_t)atomic_load_explicit(target, memory_order_acquire) +#define isc_refcount_current(target) \ + (uint_fast32_t)atomic_load_acquire(target) /** \def isc_refcount_destroy(ref) * \brief a destructor that makes sure that all references were cleared. * \param[in] ref pointer to reference counter. * \returns nothing. */ -#define isc_refcount_destroy(target) \ +#define isc_refcount_destroy(target) \ ISC_REQUIRE(isc_refcount_current(target) == 0) /** \def isc_refcount_increment0(ref) @@ -68,23 +68,41 @@ typedef atomic_uint_fast32_t isc_refcount_t; * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_increment0(target) \ - isc_refcount_increment(target) +#define isc_refcount_increment0(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_add_relaxed(target, 1); \ + INSIST(__v < UINT32_MAX); \ + __v; \ + }) /** \def isc_refcount_increment(ref) * \brief increases reference counter by 1. * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_increment(target) \ - atomic_fetch_add_explicit(target, 1, memory_order_relaxed) +#define isc_refcount_increment(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_add_relaxed(target, 1); \ + INSIST(__v > 0 && __v < UINT32_MAX); \ + __v; \ + }) /** \def isc_refcount_decrement(ref) * \brief decreases reference counter by 1. * \param[in] ref pointer to reference counter. * \returns previous value of reference counter. */ -#define isc_refcount_decrement(target) \ - atomic_fetch_sub_explicit(target, 1, memory_order_release) +#define isc_refcount_decrement(target) \ + ({ \ + /* cppcheck-suppress shadowVariable */ \ + uint_fast32_t __v; \ + __v = atomic_fetch_sub_release(target, 1); \ + INSIST(__v > 0); \ + __v; \ + }) ISC_LANG_ENDDECLS