Skip to content

Stack corrupted using vm inside domain #43135

Open
@tshemsedinov

Description

@tshemsedinov

Version

v14.19.2, v16.15.0, v18.1.0

Platform

Linux marcus 5.16.18-200.fc35.x86_64 #1 SMP PREEMPT Mon Mar 28 14:10:07 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

Subsystem

No response

What steps will reproduce the bug?

Here is a code snippet to reproduce

const vm = require('vm');
const domain = require('node:domain');

const d = domain.create();

d.run(() => {
  const src = `Promise.resolve().then(() => {
    while (1);
  });`;
  try {
    const options = { timeout: 5, microtaskMode: 'afterEvaluate' };
    vm.runInNewContext(src, {}, options);
  } catch (error) {
    console.log(error);
  }
});

Alternative method to reproduce

const vm = require('vm');
const domain = require('node:domain');

const d = domain.create();

d.run(async () => {
  const src = `Promise.resolve().then(() => {
    while (1);
  });`;
  const options = { timeout: 5, microtaskMode: 'afterEvaluate' };
  vm.runInNewContext(src, {}, options);
});

How often does it reproduce? Is there a required condition?

We need at least:

  • Any of vm.runIn...
  • Use try..cache or pass async function to domain.run
  • Wrap infinite loop into Promise to use microtasks
  • Both timeout: number and microtaskMode: 'afterEvaluate' options

What is the expected behavior?

I'd expect to catch this error with try..catch

What do you see instead?

Error: Script execution timed out after 5ms
    at Script.runInContext (node:vm:139:12)
    at Script.runInNewContext (node:vm:144:17)
    at Object.runInNewContext (node:vm:298:38)
    at Domain.<anonymous> (.../test/e.js:14:8)
    at Domain.run (node:domain:378:15)
    at Object.<anonymous> (.../test/e.js:8:3)
    at Module._compile (node:internal/modules/cjs/loader:1105:14)
    at Module._extensions..js (node:internal/modules/cjs/loader:1159:10)
    at Module.load (node:internal/modules/cjs/loader:981:32)
    at Module._load (node:internal/modules/cjs/loader:827:12) {
  code: 'ERR_SCRIPT_EXECUTION_TIMEOUT'
}
Error: async hook stack has become corrupted (actual: 3, expected: 1)
 1: 0xadb27d node::AsyncHooks::FailWithCorruptedAsyncStack(double) [node]
 2: 0xa94c58 node::InternalCallbackScope::Close() [node]
 3: 0xa94f71 node::InternalCallbackScope::~InternalCallbackScope() [node]
 4: 0xb19282 node::StartExecution(node::Environment*, std::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) [node]
 5: 0xa99217 node::LoadEnvironment(node::Environment*, std::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) [node]
 6: 0xb9b395 node::NodeMainInstance::Run() [node]
 7: 0xb1bd02 node::Start(int, char**) [node]
 8: 0x7f49f2c10f20  [/lib64/libc.so.6]
 9: 0x7f49f2c10fd0 __libc_start_main [/lib64/libc.so.6]
10: 0xa93f0e _start [node]

or for alternative case without try..catch but with async function:

Error: async hook stack has become corrupted (actual: 4, expected: 1)
 1: 0xadb27d node::AsyncHooks::FailWithCorruptedAsyncStack(double) [node]
 2: 0xa94c58 node::InternalCallbackScope::Close() [node]
 3: 0xa94f71 node::InternalCallbackScope::~InternalCallbackScope() [node]
 4: 0xb19282 node::StartExecution(node::Environment*, std::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) [node]
 5: 0xa99217 node::LoadEnvironment(node::Environment*, std::function<v8::MaybeLocal<v8::Value> (node::StartExecutionCallbackInfo const&)>) [node]
 6: 0xb9b395 node::NodeMainInstance::Run() [node]
 7: 0xb1bd02 node::Start(int, char**) [node]
 8: 0x7fc2791b1f20  [/lib64/libc.so.6]
 9: 0x7fc2791b1fd0 __libc_start_main [/lib64/libc.so.6]
10: 0xa93f0e _start [node]

Metadata

Metadata

Assignees

No one assigned

    Labels

    vmIssues and PRs related to the vm subsystem.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions