tor-browser

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

commit b46ba4b78eb9ff83adf03bbf09e8c45f058d55ba
parent 4cd49eb13b7db4af87558f8eeefd025c40063369
Author: Bryan Thrall <bthrall@mozilla.com>
Date:   Wed, 12 Nov 2025 22:02:50 +0000

Bug 1989115 - Track unsafe call with ABI state in release r=mgaudet,rhunt

Differential Revision: https://phabricator.services.mozilla.com/D268761

Diffstat:
Mjs/src/jit/MacroAssembler.cpp | 12+-----------
Mjs/src/jit/MacroAssembler.h | 2+-
Mjs/src/vm/JSContext.cpp | 12+++++-------
Mjs/src/vm/JSContext.h | 11+----------
4 files changed, 8 insertions(+), 29 deletions(-)

diff --git a/js/src/jit/MacroAssembler.cpp b/js/src/jit/MacroAssembler.cpp @@ -4885,7 +4885,6 @@ void MacroAssembler::setupAlignedABICall() { dynamicAlignment_ = false; } -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI void MacroAssembler::wasmCheckUnsafeCallWithABIPre() { // Set the JSContext::inUnsafeCallWithABI flag. loadPtr(Address(InstanceReg, wasm::Instance::offsetOfCx()), @@ -4895,6 +4894,7 @@ void MacroAssembler::wasmCheckUnsafeCallWithABIPre() { store32(Imm32(1), flagAddr); } +#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI void MacroAssembler::wasmCheckUnsafeCallWithABIPost() { // Check JSContext::inUnsafeCallWithABI was cleared as expected. Label ok; @@ -4986,7 +4986,6 @@ void MacroAssembler::callWithABINoProfiler(void* fun, ABIType result, uint32_t stackAdjust; callWithABIPre(&stackAdjust); -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI if (check == CheckUnsafeCallWithABI::Check) { // Set the JSContext::inUnsafeCallWithABI flag. push(ReturnReg); @@ -4997,7 +4996,6 @@ void MacroAssembler::callWithABINoProfiler(void* fun, ABIType result, // On arm64, SP may be < PSP now (that's OK). // eg testcase: tests/bug1375074.js } -#endif call(ImmPtr(fun)); @@ -5029,13 +5027,9 @@ CodeOffset MacroAssembler::callWithABI(wasm::BytecodeOffset bytecode, // The instance register is used in builtin thunks and must be set. bool needsBuiltinThunk = wasm::NeedsBuiltinThunk(imm); -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI // The builtin thunk exits the JIT activation, if we don't have one we must // use AutoUnsafeCallWithABI inside the builtin and check that here. bool checkUnsafeCallWithABI = !needsBuiltinThunk; -#else - bool checkUnsafeCallWithABI = false; -#endif if (needsBuiltinThunk || checkUnsafeCallWithABI) { if (instanceOffset) { loadPtr(Address(getStackPointer(), *instanceOffset + stackAdjust), @@ -5045,11 +5039,9 @@ CodeOffset MacroAssembler::callWithABI(wasm::BytecodeOffset bytecode, } } -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI if (checkUnsafeCallWithABI) { wasmCheckUnsafeCallWithABIPre(); } -#endif CodeOffset raOffset = call( wasm::CallSiteDesc(bytecode.offset(), wasm::CallSiteKind::Symbolic), imm); @@ -6398,14 +6390,12 @@ CodeOffset MacroAssembler::wasmCallBuiltinInstanceMethod( MOZ_CRASH("Unknown abi passing style for pointer"); } -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI // The builtin thunk exits the JIT activation, if we don't have one we must // use AutoUnsafeCallWithABI inside the builtin and check that here. bool checkUnsafeCallWithABI = !wasm::NeedsBuiltinThunk(builtin); if (checkUnsafeCallWithABI) { wasmCheckUnsafeCallWithABIPre(); } -#endif CodeOffset ret = call(desc, builtin); diff --git a/js/src/jit/MacroAssembler.h b/js/src/jit/MacroAssembler.h @@ -838,9 +838,9 @@ class MacroAssembler : public MacroAssemblerSpecific { void callWithABIPost(uint32_t stackAdjust, ABIType result, bool callFromWasm = false) PER_ARCH; -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI // Set the JSContext::inUnsafeCallWithABI flag using InstanceReg. void wasmCheckUnsafeCallWithABIPre(); +#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI // Check JSContext::inUnsafeCallWithABI was cleared as expected. void wasmCheckUnsafeCallWithABIPost(); #endif diff --git a/js/src/vm/JSContext.cpp b/js/src/vm/JSContext.cpp @@ -1218,10 +1218,8 @@ JSContext::JSContext(JSRuntime* runtime, const JS::ContextOptions& options) activation_(this, nullptr), profilingActivation_(nullptr), noExecuteDebuggerTop(this, nullptr), -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI inUnsafeCallWithABI(this, false), hasAutoUnsafeCallWithABI(this, false), -#endif #ifdef DEBUG liveArraySortDataInstances(this, 0), #endif @@ -1703,8 +1701,6 @@ void JSContext::suspendExecutionTracing() { #endif -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI - AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness) : cx_(TlsContext.get()), nested_(cx_ ? cx_->hasAutoUnsafeCallWithABI : false), @@ -1713,6 +1709,7 @@ AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness) // This is a helper thread doing Ion or Wasm compilation - nothing to do. return; } +#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI switch (strictness) { case UnsafeABIStrictness::NoExceptions: MOZ_ASSERT(!JS_IsExceptionPending(cx_)); @@ -1725,6 +1722,7 @@ AutoUnsafeCallWithABI::AutoUnsafeCallWithABI(UnsafeABIStrictness strictness) checkForPendingException_ = false; break; } +#endif cx_->hasAutoUnsafeCallWithABI = true; } @@ -1733,16 +1731,16 @@ AutoUnsafeCallWithABI::~AutoUnsafeCallWithABI() { if (!cx_) { return; } +#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI MOZ_ASSERT(cx_->hasAutoUnsafeCallWithABI); + MOZ_ASSERT_IF(checkForPendingException_, !JS_IsExceptionPending(cx_)); +#endif if (!nested_) { cx_->hasAutoUnsafeCallWithABI = false; cx_->inUnsafeCallWithABI = false; } - MOZ_ASSERT_IF(checkForPendingException_, !JS_IsExceptionPending(cx_)); } -#endif // JS_CHECK_UNSAFE_CALL_WITH_ABI - #ifdef __wasi__ JS_PUBLIC_API void js::IncWasiRecursionDepth(JSContext* cx) { ++JS::RootingContext::get(cx)->wasiRecursionDepth; diff --git a/js/src/vm/JSContext.h b/js/src/vm/JSContext.h @@ -458,11 +458,9 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext, return offsetof(JSContext, jitActivation); } -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI static size_t offsetOfInUnsafeCallWithABI() { return offsetof(JSContext, inUnsafeCallWithABI); } -#endif public: js::InterpreterStack& interpreterStack() { @@ -501,10 +499,8 @@ struct JS_PUBLIC_API JSContext : public JS::RootingContext, */ js::ContextData<js::EnterDebuggeeNoExecute*> noExecuteDebuggerTop; -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI js::ContextData<uint32_t> inUnsafeCallWithABI; js::ContextData<bool> hasAutoUnsafeCallWithABI; -#endif #ifdef DEBUG js::ContextData<uint32_t> liveArraySortDataInstances; @@ -1222,22 +1218,17 @@ enum UnsafeABIStrictness { // the function is not called with a pending exception, and that it does not // throw an exception itself. class MOZ_RAII AutoUnsafeCallWithABI { -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI JSContext* cx_; bool nested_; +#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI bool checkForPendingException_; #endif JS::AutoCheckCannotGC nogc; public: -#ifdef JS_CHECK_UNSAFE_CALL_WITH_ABI explicit AutoUnsafeCallWithABI( UnsafeABIStrictness strictness = UnsafeABIStrictness::NoExceptions); ~AutoUnsafeCallWithABI(); -#else - explicit AutoUnsafeCallWithABI( - UnsafeABIStrictness unused_ = UnsafeABIStrictness::NoExceptions) {} -#endif }; template <typename T>