From 7a3f4d065e50a3b1e8f63e0701e7bffd31b42417 Mon Sep 17 00:00:00 2001 From: Marcus Holland-Moritz Date: Wed, 13 Sep 2017 01:39:44 -0700 Subject: [PATCH] Fix UB from signed integer overflow in RWSpinLock Summary: The signed counters used in a couple of places can in theory (and practice) overflow, yielding UB. Use unsigned counters instead. Reviewed By: luciang, philippv Differential Revision: D5818606 fbshipit-source-id: c5928b779e76b309b00b7f6308a220e2bf6cbf79 --- folly/RWSpinLock.h | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/folly/RWSpinLock.h b/folly/RWSpinLock.h index cd8cf027..6a5436dc 100644 --- a/folly/RWSpinLock.h +++ b/folly/RWSpinLock.h @@ -190,7 +190,7 @@ class RWSpinLock { // Lockable Concept void lock() { - int count = 0; + uint_fast32_t count = 0; while (!LIKELY(try_lock())) { if (++count > 1000) std::this_thread::yield(); } @@ -204,7 +204,7 @@ class RWSpinLock { // SharedLockable Concept void lock_shared() { - int count = 0; + uint_fast32_t count = 0; while (!LIKELY(try_lock_shared())) { if (++count > 1000) std::this_thread::yield(); } @@ -222,7 +222,7 @@ class RWSpinLock { // UpgradeLockable Concept void lock_upgrade() { - int count = 0; + uint_fast32_t count = 0; while (!try_lock_upgrade()) { if (++count > 1000) std::this_thread::yield(); } @@ -603,7 +603,7 @@ class RWTicketSpinLockT { // cores allocated to this process. This is less likely than the // corresponding situation in lock_shared(), but we still want to // avoid it - int count = 0; + uint_fast32_t count = 0; QuarterInt val = __sync_fetch_and_add(&ticket.users, 1); while (val != load_acquire(&ticket.write)) { asm_volatile_pause(); @@ -653,7 +653,7 @@ class RWTicketSpinLockT { // std::this_thread::yield() is important here because we can't grab the // shared lock if there is a pending writeLockAggressive, so we // need to let threads that already have a shared lock complete - int count = 0; + uint_fast32_t count = 0; while (!LIKELY(try_lock_shared())) { asm_volatile_pause(); if (UNLIKELY((++count & 1023) == 0)) std::this_thread::yield(); -- 2.34.1