tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

lock_impl_posix.cc (4229B)


      1 // Copyright 2011 The Chromium Authors
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "base/synchronization/lock_impl.h"
      6 
      7 #include <ostream>
      8 #include <string>
      9 
     10 #include "base/check_op.h"
     11 #include "base/posix/safe_strerror.h"
     12 #include "base/synchronization/lock.h"
     13 #include "base/synchronization/synchronization_buildflags.h"
     14 #include "build/build_config.h"
     15 
     16 namespace base {
     17 namespace internal {
     18 
     19 namespace {
     20 
     21 #if DCHECK_IS_ON()
     22 const char* AdditionalHintForSystemErrorCode(int error_code) {
     23  switch (error_code) {
     24    case EINVAL:
     25      return "Hint: This is often related to a use-after-free.";
     26    default:
     27      return "";
     28  }
     29 }
     30 #endif  // DCHECK_IS_ON()
     31 
     32 std::string SystemErrorCodeToString(int error_code) {
     33 #if DCHECK_IS_ON()
     34  return base::safe_strerror(error_code) + ". " +
     35         AdditionalHintForSystemErrorCode(error_code);
     36 #else   // DCHECK_IS_ON()
     37  return std::string();
     38 #endif  // DCHECK_IS_ON()
     39 }
     40 
     41 }  // namespace
     42 
     43 #if DCHECK_IS_ON()
     44 // These are out-of-line so that the .h file doesn't have to include ostream.
     45 void dcheck_trylock_result(int rv) {
     46  DCHECK(rv == 0 || rv == EBUSY)
     47      << ". " << base::internal::SystemErrorCodeToString(rv);
     48 }
     49 
     50 void dcheck_unlock_result(int rv) {
     51  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     52 }
     53 #endif
     54 
     55 // Determines which platforms can consider using priority inheritance locks. Use
     56 // this define for platform code that may not compile if priority inheritance
     57 // locks aren't available. For this platform code,
     58 // PRIORITY_INHERITANCE_LOCKS_POSSIBLE() is a necessary but insufficient check.
     59 // Lock::PriorityInheritanceAvailable still must be checked as the code may
     60 // compile but the underlying platform still may not correctly support priority
     61 // inheritance locks.
     62 #if BUILDFLAG(IS_NACL) || BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA)
     63 #define PRIORITY_INHERITANCE_LOCKS_POSSIBLE() 0
     64 #else
     65 #define PRIORITY_INHERITANCE_LOCKS_POSSIBLE() 1
     66 #endif
     67 
     68 LockImpl::LockImpl() {
     69  pthread_mutexattr_t mta;
     70  int rv = pthread_mutexattr_init(&mta);
     71  DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     72 #if PRIORITY_INHERITANCE_LOCKS_POSSIBLE()
     73  if (PriorityInheritanceAvailable()) {
     74    rv = pthread_mutexattr_setprotocol(&mta, PTHREAD_PRIO_INHERIT);
     75    DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     76  }
     77 #endif
     78 #ifndef NDEBUG
     79  // In debug, setup attributes for lock error checking.
     80  rv = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK);
     81  DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     82 #endif
     83  rv = pthread_mutex_init(&native_handle_, &mta);
     84  DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     85  rv = pthread_mutexattr_destroy(&mta);
     86  DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     87 }
     88 
     89 LockImpl::~LockImpl() {
     90  int rv = pthread_mutex_destroy(&native_handle_);
     91  DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     92 }
     93 
     94 void LockImpl::LockInternal() {
     95  int rv = pthread_mutex_lock(&native_handle_);
     96  DCHECK_EQ(rv, 0) << ". " << SystemErrorCodeToString(rv);
     97 }
     98 
     99 // static
    100 bool LockImpl::PriorityInheritanceAvailable() {
    101 #if BUILDFLAG(ENABLE_MUTEX_PRIORITY_INHERITANCE)
    102  return true;
    103 #elif PRIORITY_INHERITANCE_LOCKS_POSSIBLE() && BUILDFLAG(IS_APPLE)
    104  return true;
    105 #else
    106  // Security concerns prevent the use of priority inheritance mutexes on Linux.
    107  //   * CVE-2010-0622 - Linux < 2.6.33-rc7, wake_futex_pi possible DoS.
    108  //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0622
    109  //   * CVE-2012-6647 - Linux < 3.5.1, futex_wait_requeue_pi possible DoS.
    110  //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-6647
    111  //   * CVE-2014-3153 - Linux <= 3.14.5, futex_requeue, privilege escalation.
    112  //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3153
    113  //
    114  // If the above were all addressed, we still need a runtime check to deal with
    115  // the bug below.
    116  //   * glibc Bug 14652: https://sourceware.org/bugzilla/show_bug.cgi?id=14652
    117  //     Fixed in glibc 2.17.
    118  //     Priority inheritance mutexes may deadlock with condition variables
    119  //     during reacquisition of the mutex after the condition variable is
    120  //     signalled.
    121  return false;
    122 #endif
    123 }
    124 
    125 }  // namespace internal
    126 }  // namespace base