Skip to content

JS_ThrowStackOverflow may overflow stack itself #893

Open
@Bargest

Description

@Bargest

Hello,

QuickJS supports stack limiting with JS_SetMaxStackSize(), and many operations check remaining stack size before alloca() or calling functions. These checks call JS_ThrowStackOverflow(), which should throw corresponding exception. Obviously this exception has a stacktrace.
But the problem is that build_backtrace() function consumes huge amount of stack itself. For example, just this line implies x64 JSCallSiteData structs, each of them is x3 JSValue (+ 9 bytes + align), and each JSValue may be up to 16 bytes on x64 machine (depending on flags). This gives us 64 * aligned(3 * 16 + 9) = 3840 bytes. The full call chain performed to fill backtrace also includes other stack-heavy things, like char buf[256]. Since the exception itself was thrown because we've already reached stack limit, there is a risk of "physically" overflowing the stack if the limit was configured somewhat near the real stack size.

For now the only workaround is to set limit way lower than real stack size, but the needed spare space seems to be unpredictable.
Proposed solutions:

  1. Calculate and enforce maximum stack consumption for JS_ThrowStackOverflow() and specify it in documentation;
  2. Make build_backtrace() and other corresponding functions less stack-heavy, moving every possible local value on (pre-allocated?) heap buffer;
  3. Add some stack checks to throwing-related functions and fallback to skipping backtrace if building stacktrace is impossible.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions