tor-browser

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

lock_impl_posix.cc (3402B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      4 // Use of this source code is governed by a BSD-style license that can be
      5 // found in the LICENSE file.
      6 
      7 #include "base/lock_impl.h"
      8 
      9 #include <errno.h>
     10 #include <string.h>
     11 
     12 #include "base/logging.h"
     13 #include "base/lock.h"
     14 
     15 namespace base {
     16 namespace internal {
     17 
     18 // Determines which platforms can consider using priority inheritance locks. Use
     19 // this define for platform code that may not compile if priority inheritance
     20 // locks aren't available. For this platform code,
     21 // PRIORITY_INHERITANCE_LOCKS_POSSIBLE() is a necessary but insufficient check.
     22 // Lock::PriorityInheritanceAvailable still must be checked as the code may
     23 // compile but the underlying platform still may not correctly support priority
     24 // inheritance locks.
     25 #if defined(ANDROID)
     26 #  define PRIORITY_INHERITANCE_LOCKS_POSSIBLE() 0
     27 #else
     28 #  define PRIORITY_INHERITANCE_LOCKS_POSSIBLE() 1
     29 #endif
     30 
     31 LockImpl::LockImpl() {
     32  pthread_mutexattr_t mta;
     33  int rv = pthread_mutexattr_init(&mta);
     34  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     35 #if PRIORITY_INHERITANCE_LOCKS_POSSIBLE()
     36  if (PriorityInheritanceAvailable()) {
     37    rv = pthread_mutexattr_setprotocol(&mta, PTHREAD_PRIO_INHERIT);
     38    DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     39  }
     40 #endif
     41 #ifndef NDEBUG
     42  // In debug, setup attributes for lock error checking.
     43  rv = pthread_mutexattr_settype(&mta, PTHREAD_MUTEX_ERRORCHECK);
     44  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     45 #endif
     46  rv = pthread_mutex_init(&native_handle_, &mta);
     47  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     48  rv = pthread_mutexattr_destroy(&mta);
     49  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     50 }
     51 
     52 LockImpl::~LockImpl() {
     53  int rv = pthread_mutex_destroy(&native_handle_);
     54  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     55 }
     56 
     57 bool LockImpl::Try() {
     58  int rv = pthread_mutex_trylock(&native_handle_);
     59  DCHECK(rv == 0 || rv == EBUSY) << ". " << strerror(rv);
     60  return rv == 0;
     61 }
     62 
     63 void LockImpl::Lock() {
     64  int rv = pthread_mutex_lock(&native_handle_);
     65  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     66 }
     67 
     68 void LockImpl::Unlock() {
     69  int rv = pthread_mutex_unlock(&native_handle_);
     70  DCHECK_EQ(rv, 0) << ". " << strerror(rv);
     71 }
     72 
     73 // static
     74 bool LockImpl::PriorityInheritanceAvailable() {
     75 #if PRIORITY_INHERITANCE_LOCKS_POSSIBLE() && defined(XP_DARWIN)
     76  return true;
     77 #else
     78  // Security concerns prevent the use of priority inheritance mutexes on Linux.
     79  //   * CVE-2010-0622 - wake_futex_pi unlocks incorrect, possible DoS.
     80  //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2010-0622
     81  //   * CVE-2012-6647 - Linux < 3.5.1, futex_wait_requeue_pi possible DoS.
     82  //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-6647
     83  //   * CVE-2014-3153 - Linux <= 3.14.5, futex_requeue, privilege escalation.
     84  //     https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2014-3153
     85  //
     86  // If the above were all addressed, we still need a runtime check to deal with
     87  // the bug below.
     88  //   * glibc Bug 14652: https://sourceware.org/bugzilla/show_bug.cgi?id=14652
     89  //     Fixed in glibc 2.17.
     90  //     Priority inheritance mutexes may deadlock with condition variables
     91  //     during recacquisition of the mutex after the condition variable is
     92  //     signalled.
     93  return false;
     94 #endif
     95 }
     96 
     97 }  // namespace internal
     98 }  // namespace base