Thanks to visit codestin.com
Credit goes to github.com

Skip to content

src: validate stdio entries in process_wrap#61978

Open
dhruv7539 wants to merge 4 commits intonodejs:mainfrom
dhruv7539:codex/fix-process-wrap-stdio-entries
Open

src: validate stdio entries in process_wrap#61978
dhruv7539 wants to merge 4 commits intonodejs:mainfrom
dhruv7539:codex/fix-process-wrap-stdio-entries

Conversation

@dhruv7539
Copy link

This guards ProcessWrap::ParseStdioOptions() against non-object entries in options.stdio.

Before this change, each options.stdio[i] value was cast directly with val.As(). If Array.prototype is polluted (for example with a setter at index 2), child_process.spawn() can hit a fatal abort (FATAL ERROR: v8::ToLocalChecked Empty MaybeLocal) instead of throwing a JS error.

This patch:

  • validates each options.stdio[i] entry is an object and throws ERR_INVALID_ARG_TYPE otherwise
  • adds a regression test (test/parallel/test-child-process-array-prototype-setter.js) that reproduces the prototype-pollution scenario in a subprocess and verifies Node does not abort

Refs: #56531

@nodejs-github-bot nodejs-github-bot added c++ Issues and PRs that require attention from people who are familiar with C++. child_process Issues and PRs related to the child_process subsystem. needs-ci PRs that need a full CI run. labels Feb 25, 2026
@addaleax addaleax added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Feb 25, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Feb 25, 2026
@nodejs-github-bot
Copy link
Collaborator

@dhruv7539
Copy link
Author

Follow-up fix pushed in 9aa1a1d: the new test regex was over-escaped (matching literal backslashes), which caused the CI failure.

Could a collaborator please add the request-ci label to retrigger Jenkins for this commit?

@dhruv7539 dhruv7539 requested a review from addaleax February 25, 2026 18:25
@addaleax addaleax added request-ci Add this label to start a Jenkins CI on a PR. and removed author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Feb 25, 2026
@addaleax
Copy link
Member

@dhruv7539 The linter is failing here anyway, that should be addressed first

@codecov
Copy link

codecov bot commented Feb 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 89.76%. Comparing base (2ebe496) to head (bdb66fb).
⚠️ Report is 39 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff             @@
##             main   #61978      +/-   ##
==========================================
- Coverage   89.77%   89.76%   -0.01%     
==========================================
  Files         674      674              
  Lines      205670   205709      +39     
  Branches    39426    39437      +11     
==========================================
+ Hits       184635   184664      +29     
- Misses      13272    13295      +23     
+ Partials     7763     7750      -13     
Files with missing lines Coverage Δ
src/process_wrap.cc 70.96% <100.00%> (+1.29%) ⬆️

... and 50 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@dhruv7539
Copy link
Author

Pushed follow-up commit bdb66fb to fix the clang-format failure in src/process_wrap.cc.

Could a collaborator please add the request-ci label so Jenkins runs on this latest commit?

@dhruv7539 dhruv7539 requested a review from addaleax February 25, 2026 22:08
@dhruv7539
Copy link
Author

Quick follow-up: I pushed commit bdb66fb to fix the format-cpp issue in src/process_wrap.cc.

Could a collaborator please trigger CI (request-ci) for this latest commit when convenient?

@dhruv7539
Copy link
Author

Quick follow-up on this PR: the latest branch head already includes the format/lint fix in commit bdb66fb.

If a collaborator can trigger request-ci for the current head when convenient, I can handle any remaining CI feedback right away.

@addaleax addaleax added author ready PRs that have at least one approval, no pending requests for changes, and a CI started. request-ci Add this label to start a Jenkins CI on a PR. labels Mar 2, 2026
@github-actions github-actions bot removed the request-ci Add this label to start a Jenkins CI on a PR. label Mar 2, 2026
@nodejs-github-bot
Copy link
Collaborator

@nodejs-github-bot
Copy link
Collaborator

@addaleax addaleax removed the author ready PRs that have at least one approval, no pending requests for changes, and a CI started. label Mar 2, 2026
@addaleax
Copy link
Member

addaleax commented Mar 2, 2026

@dhruv7539 Looks like the Windows failures are real:

duration_ms: 326.019
exitcode: 1
severity: fail
stack: |-
  [process 10076]: --- stderr ---

  [process 10076]: --- stdout ---
  undefined

  [process 10076]: status = 0, signal = null
  c:\workspace\node-test-binary-windows-js-suites\node\test\common\child_process.js:112
      throw error;
      ^

  Error: - stdout did not match expectation, checker throws:
  AssertionError [ERR_ASSERTION]: The input did not match the regular expression /^ERR_INVALID_ARG_TYPE\r?\n$/. Input:

  'undefined\n'

      at stdout (c:\workspace\node-test-binary-windows-js-suites\node\test\parallel\test-child-process-array-prototype-setter.js:24:12)
      at checkOutput (c:\workspace\node-test-binary-windows-js-suites\node\test\common\child_process.js:52:7)
      at expectSyncExit (c:\workspace\node-test-binary-windows-js-suites\node\test\common\child_process.js:129:32)
      at spawnSyncAndAssert (c:\workspace\node-test-binary-windows-js-suites\node\test\common\child_process.js:155:10)
      at Object.<anonymous> (c:\workspace\node-test-binary-windows-js-suites\node\test\parallel\test-child-process-array-prototype-setter.js:22:1)
      at Module._compile (node:internal/modules/cjs/loader:1811:14)
      at Object..js (node:internal/modules/cjs/loader:1951:10)
      at Module.load (node:internal/modules/cjs/loader:1532:32)
      at Module._load (node:internal/modules/cjs/loader:1334:12)
      at wrapModuleLoad (node:internal/modules/cjs/loader:255:19) {
    generatedMessage: true,
    code: 'ERR_ASSERTION',
    actual: 'undefined\n',
    expected: /^ERR_INVALID_ARG_TYPE\r?\n$/,
    operator: 'match',
    diff: 'simple'
  }
      at Object.<anonymous> (c:\workspace\node-test-binary-windows-js-suites\node\test\parallel\test-child-process-array-prototype-setter.js:22:1)
      at Module._compile (node:internal/modules/cjs/loader:1811:14)
      at Object..js (node:internal/modules/cjs/loader:1951:10)
      at Module.load (node:internal/modules/cjs/loader:1532:32)
      at Module._load (node:internal/modules/cjs/loader:1334:12)
      at wrapModuleLoad (node:internal/modules/cjs/loader:255:19)
      at Module.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:154:5)
      at node:internal/main/run_main_module:33:47 {
    command: 'c:\\workspace\\node-test-binary-windows-js-suites\\node\\Release\\node.exe -e \n' +
      "Object.defineProperty(Array.prototype, '2', {\n" +
      '  __proto__: null,\n' +
      '  set() {},\n' +
      '  configurable: true,\n' +
      '});\n' +
      '\n' +
      'try {\n' +
      "  require('child_process').spawn(process.execPath, ['-e', '0']);\n" +
      "  console.log('NO_ERROR');\n" +
      '} catch (error) {\n' +
      '  console.log(error.code);\n' +
      '}\n'
  }

@dhruv7539
Copy link
Author

dhruv7539 commented Mar 3, 2026

Pushed follow-up commit da38e2e. The Windows failure was coming from JS-side stdio normalization still skipping sparse entries and appending via Array.prototype, so inherited setters could still interfere before process_wrap saw the values.

This updates getValidStdio() to iterate sparse entries explicitly and append with Object.defineProperty(), and adjusts the regression test to assert the spawn path now succeeds without hitting the fatal crash path.

Could a collaborator please trigger request-ci for the latest commit when convenient?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

c++ Issues and PRs that require attention from people who are familiar with C++. child_process Issues and PRs related to the child_process subsystem. needs-ci PRs that need a full CI run.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants