From: Marcus Holland-Moritz Date: Wed, 13 Sep 2017 08:39:44 +0000 (-0700) Subject: Fix UB from signed integer overflow in RWSpinLock X-Git-Tag: v2017.09.18.00~9 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=7a3f4d065e50a3b1e8f63e0701e7bffd31b42417;p=folly.git 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 --- 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();