From 52008a0110a32995c60dc6d556ebb8b94ffbaab6 Mon Sep 17 00:00:00 2001 From: Alexander Rosenberg Date: Mon, 8 Sep 2025 17:59:50 -0700 Subject: [PATCH] Fix unprotected access in refcount_context_num_refs --- include/refcount/config.h.in | 6 ------ include/refcount/refcount.h | 15 ++++++++++++++- 2 files changed, 14 insertions(+), 7 deletions(-) diff --git a/include/refcount/config.h.in b/include/refcount/config.h.in index 1648b96..814d661 100644 --- a/include/refcount/config.h.in +++ b/include/refcount/config.h.in @@ -3,10 +3,4 @@ #cmakedefine REFCOUNT_HAS_THREADS -#if defined(REFCOUNT_HAS_THREADS) \ - && (!defined(__STDC_VERSION__) || __STDC_VERSION__ < 201112L) -# error \ - "RefCount needs to be compiled with at least C11 for thread support to work." -#endif - #endif diff --git a/include/refcount/refcount.h b/include/refcount/refcount.h index e2db9c8..698778f 100644 --- a/include/refcount/refcount.h +++ b/include/refcount/refcount.h @@ -162,7 +162,20 @@ static inline bool refcount_context_is_static(const RefcountContext *ctx, */ static inline uint64_t refcount_context_num_refs(const RefcountContext *ctx, void *obj) { - return REFCOUNT_OBJECT_ENTRY(ctx, obj)->impl.counted.ref_count; +#ifdef REFCOUNT_HAS_THREADS + if (!mtx_lock(&REFCOUNT_OBJECT_ENTRY(ctx, obj)->weak_ref->mtx)) { + // just try our best to estimate, if we are on a platform where 64bit + // stores are not atomic (or this is not aligned properly), this might + // race and give a bogus number + return REFCOUNT_OBJECT_ENTRY(ctx, obj)->impl.counted.ref_count; + } +#endif + const uint64_t count = + REFCOUNT_OBJECT_ENTRY(ctx, obj)->impl.counted.ref_count; +#ifdef REFCOUNT_HAS_THREADS + mtx_unlock(&REFCOUNT_OBJECT_ENTRY(ctx, obj)->weak_ref->mtx); +#endif + return count; } bool refcount_context_init_obj(const RefcountContext *ctx, void *obj);