mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-28 23:31:56 +00:00
Bug 1704771 part 9 - Add recursion limiter. r=jandem
WASI doesn't support catching call-stack overflows with stack-pointer checks, so custom RecursionLimiter is used to directly count entries to certain functions and report stack overflows. Differential Revision: https://phabricator.services.mozilla.com/D111813
This commit is contained in:
parent
98af369b22
commit
a6f2b3ce51
@ -993,6 +993,14 @@ class RootingContext {
|
||||
/* Limit pointer for checking native stack consumption. */
|
||||
uintptr_t nativeStackLimit[StackKindCount];
|
||||
|
||||
#ifdef __wasi__
|
||||
// For WASI we can't catch call-stack overflows with stack-pointer checks, so
|
||||
// we count recursion depth with RAII based AutoCheckRecursionLimit.
|
||||
uint32_t wasiRecursionDepth = 0u;
|
||||
|
||||
static constexpr uint32_t wasiRecursionDepthLimit = 100u;
|
||||
#endif // __wasi__
|
||||
|
||||
static const RootingContext* get(const JSContext* cx) {
|
||||
return reinterpret_cast<const RootingContext*>(cx);
|
||||
}
|
||||
|
@ -61,8 +61,26 @@ class MOZ_RAII AutoCheckRecursionLimit {
|
||||
|
||||
JS_FRIEND_API bool runningWithTrustedPrincipals(JSContext* cx) const;
|
||||
|
||||
#ifdef __wasi__
|
||||
// The JSContext outlives AutoCheckRecursionLimit so it is safe to use raw
|
||||
// pointer here.
|
||||
JSContext* cx_;
|
||||
#endif // __wasi__
|
||||
|
||||
public:
|
||||
explicit MOZ_ALWAYS_INLINE AutoCheckRecursionLimit(JSContext* cx) {}
|
||||
explicit MOZ_ALWAYS_INLINE AutoCheckRecursionLimit(JSContext* cx) {
|
||||
#ifdef __wasi__
|
||||
cx_ = cx;
|
||||
++JS::RootingContext::get(cx_)->wasiRecursionDepth;
|
||||
#endif // __wasi__
|
||||
}
|
||||
|
||||
MOZ_ALWAYS_INLINE ~AutoCheckRecursionLimit() {
|
||||
#ifdef __wasi__
|
||||
MOZ_ASSERT(JS::RootingContext::get(cx_)->wasiRecursionDepth > 0);
|
||||
--JS::RootingContext::get(cx_)->wasiRecursionDepth;
|
||||
#endif // __wasi__
|
||||
}
|
||||
|
||||
AutoCheckRecursionLimit(const AutoCheckRecursionLimit&) = delete;
|
||||
void operator=(const AutoCheckRecursionLimit&) = delete;
|
||||
@ -89,6 +107,17 @@ MOZ_ALWAYS_INLINE bool AutoCheckRecursionLimit::checkLimitImpl(uintptr_t limit,
|
||||
void* sp) const {
|
||||
JS_STACK_OOM_POSSIBLY_FAIL();
|
||||
|
||||
#ifdef __wasi__
|
||||
// WASI has two limits:
|
||||
// 1) The stack pointer in linear memory that grows to zero. See --stack-first
|
||||
// in js/src/shell/moz.build. 2) The wasiRecursionDepth_ that counts recursion
|
||||
// depth. Here we should check both.
|
||||
if (JS::RootingContext::get(cx_)->wasiRecursionDepth >=
|
||||
JS::RootingContext::wasiRecursionDepthLimit) {
|
||||
return false;
|
||||
}
|
||||
#endif // __wasi__
|
||||
|
||||
#if JS_STACK_GROWTH_DIRECTION > 0
|
||||
return MOZ_LIKELY(uintptr_t(sp) < limit);
|
||||
#else
|
||||
|
Loading…
Reference in New Issue
Block a user