tor-browser

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

Utility.cpp (5358B)


      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 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /* Various JS utility functions. */
      8 
      9 #include "js/Utility.h"
     10 
     11 #include "mozilla/Assertions.h"
     12 #include "mozilla/Atomics.h"
     13 #include "mozilla/Maybe.h"
     14 #include "mozilla/ThreadLocal.h"
     15 
     16 #include <stdio.h>
     17 
     18 #include "jstypes.h"
     19 
     20 #include "util/Poison.h"
     21 #include "vm/HelperThreads.h"
     22 #include "vm/JSContext.h"
     23 
     24 using namespace js;
     25 
     26 using mozilla::Maybe;
     27 
     28 #if defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
     29 /* For OOM testing functionality in Utility.h. */
     30 namespace js {
     31 
     32 mozilla::Atomic<AutoEnterOOMUnsafeRegion*> AutoEnterOOMUnsafeRegion::owner_;
     33 
     34 namespace oom {
     35 
     36 JS_PUBLIC_DATA FailureSimulator simulator;
     37 static MOZ_THREAD_LOCAL(uint32_t) threadType;
     38 
     39 bool InitThreadType() { return threadType.init(); }
     40 
     41 void SetThreadType(ThreadType type) { threadType.set(type); }
     42 
     43 uint32_t GetThreadType(void) { return threadType.get(); }
     44 
     45 static inline bool IsHelperThreadType(uint32_t thread) {
     46  return thread != THREAD_TYPE_NONE && thread != THREAD_TYPE_MAIN;
     47 }
     48 
     49 void FailureSimulator::simulateFailureAfter(Kind kind, uint64_t checks,
     50                                            uint32_t thread, bool always) {
     51  Maybe<AutoLockHelperThreadState> lock;
     52  if (IsHelperThreadType(targetThread_) || IsHelperThreadType(thread)) {
     53    lock.emplace();
     54    WaitForAllHelperThreads(lock.ref());
     55  }
     56 
     57  MOZ_ASSERT(counter_ + checks > counter_);
     58  MOZ_ASSERT(thread > js::THREAD_TYPE_NONE && thread < js::THREAD_TYPE_MAX);
     59  targetThread_ = thread;
     60  maxChecks_ = counter_ + checks;
     61  failAlways_ = always;
     62  kind_ = kind;
     63 }
     64 
     65 void FailureSimulator::reset() {
     66  Maybe<AutoLockHelperThreadState> lock;
     67  if (IsHelperThreadType(targetThread_)) {
     68    lock.emplace();
     69    WaitForAllHelperThreads(lock.ref());
     70  }
     71 
     72  targetThread_ = THREAD_TYPE_NONE;
     73  maxChecks_ = UINT64_MAX;
     74  failAlways_ = false;
     75  kind_ = Kind::Nothing;
     76 }
     77 
     78 }  // namespace oom
     79 }  // namespace js
     80 #endif  // defined(DEBUG) || defined(JS_OOM_BREAKPOINT)
     81 
     82 #if defined(FUZZING)
     83 namespace js {
     84 namespace oom {
     85 JS_PUBLIC_DATA size_t largeAllocLimit = 0;
     86 void InitLargeAllocLimit() {
     87  char* limitStr = getenv("MOZ_FUZZ_LARGE_ALLOC_LIMIT");
     88  if (limitStr) {
     89    largeAllocLimit = atoll(limitStr);
     90  }
     91 }
     92 }  // namespace oom
     93 }  // namespace js
     94 #endif
     95 
     96 JS_PUBLIC_DATA arena_id_t js::MallocArena;
     97 JS_PUBLIC_DATA arena_id_t js::BackgroundMallocArena;
     98 JS_PUBLIC_DATA arena_id_t js::ArrayBufferContentsArena;
     99 JS_PUBLIC_DATA arena_id_t js::StringBufferArena;
    100 
    101 void js::InitMallocAllocator() {
    102  arena_params_t mallocArenaParams;
    103  mallocArenaParams.mMaxDirtyIncreaseOverride = 5;
    104  mallocArenaParams.mLabel = "JS malloc";
    105  MallocArena = moz_create_arena_with_params(&mallocArenaParams);
    106  BackgroundMallocArena = moz_create_arena_with_params(&mallocArenaParams);
    107 
    108  arena_params_t params;
    109  params.mMaxDirtyIncreaseOverride = 5;
    110  params.mFlags |= ARENA_FLAG_RANDOMIZE_SMALL_ENABLED;
    111  params.mLabel = "Array buffer contents";
    112  ArrayBufferContentsArena = moz_create_arena_with_params(&params);
    113  params.mLabel = "String buffer contents";
    114  StringBufferArena = moz_create_arena_with_params(&params);
    115 }
    116 
    117 void js::ShutDownMallocAllocator() {
    118  // Until Bug 1364359 is fixed it is unsafe to call moz_dispose_arena.
    119  // moz_dispose_arena(MallocArena);
    120  // moz_dispose_arena(ArrayBufferContentsArena);
    121 }
    122 
    123 extern void js::AssertJSStringBufferInCorrectArena(const void* ptr) {
    124 //  `jemalloc_ptr_info()` only exists if MOZ_MEMORY is defined, and it only
    125 //  returns an arenaId if MOZ_DEBUG is defined. Otherwise, this function is
    126 //  a no-op.
    127 #if defined(MOZ_MEMORY) && defined(MOZ_DEBUG)
    128  if (ptr && !TlsContext.get()->nursery().isInside(ptr)) {
    129    jemalloc_ptr_info_t ptrInfo{};
    130    jemalloc_ptr_info(ptr, &ptrInfo);
    131    MOZ_ASSERT(ptrInfo.tag != TagUnknown);
    132    MOZ_ASSERT(ptrInfo.arenaId == js::StringBufferArena);
    133  }
    134 #endif
    135 }
    136 
    137 JS_PUBLIC_API void JS_Assert(const char* s, const char* file, int ln) {
    138  MOZ_ReportAssertionFailure(s, file, ln);
    139  MOZ_CRASH();
    140 }
    141 
    142 #ifdef __linux__
    143 
    144 #  include <malloc.h>
    145 #  include <stdlib.h>
    146 
    147 namespace js {
    148 
    149 // This function calls all the vanilla heap allocation functions.  It is never
    150 // called, and exists purely to help config/check_vanilla_allocations.py.  See
    151 // that script for more details.
    152 extern MOZ_COLD void AllTheNonBasicVanillaNewAllocations() {
    153  // posix_memalign and aligned_alloc aren't available on all Linux
    154  // configurations.
    155  // valloc was deprecated in Android 5.0
    156  // char* q;
    157  // posix_memalign((void**)&q, 16, 16);
    158 
    159  intptr_t p = intptr_t(malloc(16)) + intptr_t(calloc(1, 16)) +
    160               intptr_t(realloc(nullptr, 16)) + intptr_t(new char) +
    161               intptr_t(new char) + intptr_t(new char) +
    162               intptr_t(new char[16]) + intptr_t(memalign(16, 16)) +
    163               // intptr_t(q) +
    164               // intptr_t(aligned_alloc(16, 16)) +
    165               // intptr_t(valloc(4096)) +
    166               intptr_t(strdup("dummy"));
    167 
    168  printf("%u\n", uint32_t(p));  // make sure |p| is not optimized away
    169 
    170  free((int*)p);  // this would crash if ever actually called
    171 
    172  MOZ_CRASH();
    173 }
    174 
    175 }  // namespace js
    176 
    177 #endif  // __linux__