tor-browser

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

namespace_sandbox.inc (1809B)


      1 #if defined(LIBC_GLIBC)
      2 // The first few fields of glibc's struct pthread.  The full
      3 // definition is in:
      4 // https://sourceware.org/git/?p=glibc.git;a=blob;f=nptl/descr.h;hb=95a73392580761abc62fc9b1386d232cd55878e9#l121
      5 struct glibc_pthread {
      6  union {
      7 #if defined(ARCH_CPU_X86_64)
      8    // On x86_64, sizeof(tcbhead_t) > sizeof(void*)*24.
      9    // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/x86_64/nptl/tls.h;hb=95a73392580761abc62fc9b1386d232cd55878e9#l65
     10    // For all other architectures, sizeof(tcbhead_t) <= sizeof(void*)*24.
     11    // https://sourceware.org/git/?p=glibc.git&a=search&h=HEAD&st=grep&s=%7D+tcbhead_t
     12    char header[704];
     13 #endif
     14    void* padding[24];
     15  } header;
     16  void* list[2];
     17  pid_t tid;
     18 };
     19 
     20 pid_t GetGlibcCachedTid() {
     21  pthread_mutex_t lock = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
     22  CHECK_EQ(0, pthread_mutex_lock(&lock));
     23  pid_t tid = lock.__data.__owner;
     24  CHECK_EQ(0, pthread_mutex_unlock(&lock));
     25  CHECK_EQ(0, pthread_mutex_destroy(&lock));
     26  return tid;
     27 }
     28 
     29 void MaybeUpdateGlibcTidCache() {
     30  // After the below CL, glibc does not does not reset the cached
     31  // TID/PID on clone(), but pthread depends on it being up-to-date.
     32  // This CL was introduced in glibc 2.25, and backported to 2.24 on
     33  // at least Debian and Fedora.  This is a workaround that updates
     34  // the cache manually.
     35  // https://sourceware.org/git/?p=glibc.git;a=commit;h=c579f48edba88380635ab98cb612030e3ed8691e
     36  pid_t real_tid = sys_gettid();
     37  pid_t cached_tid = GetGlibcCachedTid();
     38  if (cached_tid != real_tid) {
     39    pid_t* cached_tid_location =
     40        &reinterpret_cast<struct glibc_pthread*>(pthread_self())->tid;
     41    CHECK_EQ(cached_tid, *cached_tid_location);
     42    *cached_tid_location = real_tid;
     43    CHECK_EQ(real_tid, GetGlibcCachedTid());
     44  }
     45 }
     46 #endif  // defined(LIBC_GLIBC)