GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — IPC “advanced” mode length parsing allows malformed frames to crash parent process · Issue #61312 · nodejs/node

IPC “advanced” mode length parsing allows malformed frames to crash parent process #61312

New issue
Copy link
New issue
Copy link
Closed
#61344
Closed
IPC “advanced” mode length parsing allows malformed frames to crash parent process#61312
#61344
Copy link

Description

@HO-9
HO-9
opened on Jan 8, 2026
Issue body actions

Version

24.11.1

Platform

Linux

Subsystem

child_process

What steps will reproduce the bug?

run: node parent.js

parent.js

'use strict';

const { fork } = require('child_process');

const child = fork(require.resolve('./child.js'), {
  serialization: 'advanced',
  stdio: ['inherit', 'inherit', 'inherit', 'ipc'],
});

child.on('exit', (code, signal) => {
  console.log('child exit', code, signal);
});

setTimeout(() => {}, 60_000);

child.js

'use strict';

const fs = require('fs');

const fd = (process.channel && process.channel.fd) ?? Number(process.env.NODE_CHANNEL_FD);
if (!Number.isInteger(fd)) {
  throw new Error('IPC channel fd not available. Run via parent.js (fork with ipc).');
}

const payload = Buffer.from([0x80, 0x00, 0x00, 0x00]);
fs.writeSync(fd, payload);
process.exit(0);

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

Reproduces 100% with this PoC.
Required condition: fork() with { serialization: 'advanced' } and the child writes a malformed IPC length prefix (0x80000000)

What is the expected behavior? Why is that the expected behavior?

The parent process should not crash. It should reject or ignore malformed IPC frames and continue or fail gracefully.
IPC is an untrusted boundary between processes; malformed frames should be handled defensively rather than crashing the parent.

What do you see instead?

The parent process crashes at deserializer.readHeader().

node:internal/child_process/serialization:102
      deserializer.readHeader();
                   ^

Error: Unable to deserialize cloned data due to invalid or unsupported version.
    at parseChannelMessages (node:internal/child_process/serialization:102:20)
    at parseChannelMessages.next (<anonymous>)
    at channel.onread (node:internal/child_process:623:18)

Node.js v24.11.1

Additional information

Problematic code section (internal/child_process/serialization.js):

const fullMessageSize = (
  messageBufferHead[0] << 24 |
  messageBufferHead[1] << 16 |
  messageBufferHead[2] << 8 |
  messageBufferHead[3]
) + 4;

if (channel[kMessageBufferSize] < fullMessageSize) break;

const deserializer = new ChildProcessDeserializer(
  TypedArrayPrototypeSubarray(concatenatedBuffer, 4, fullMessageSize),
);

deserializer.readHeader();

The signed 32‑bit length parse allows negative sizes; the check is bypassed and deserialization of a truncated buffer throws.

Activity

  1. islandryu
    added a commit that references this issue on Jan 11, 2026

    child_process: treat ipc length header as unsigned uint32

    180643a
  2. nodejs-github-bot
    added a commit that references this issue on Jan 19, 2026

    child_process: treat ipc length header as unsigned uint32

    5f982e2
  3. nodejs-github-bot
    closed this as completedin #61344on Jan 19, 2026
  4. aduh95
    added a commit that references this issue on Jan 20, 2026

    child_process: treat ipc length header as unsigned uint32

    d8a1cde
  5. aduh95
    added a commit that references this issue on Jan 27, 2026

    child_process: treat ipc length header as unsigned uint32

    d2586b7
  6. aduh95
    added 6 commits that reference this issue on Feb 17, 2026

    child_process: treat ipc length header as unsigned uint32

    3defc1b

    child_process: treat ipc length header as unsigned uint32

    4927ae5

    child_process: treat ipc length header as unsigned uint32

    0cc63e6

    child_process: treat ipc length header as unsigned uint32

    ac28e05

    child_process: treat ipc length header as unsigned uint32

    72c1e03

    child_process: treat ipc length header as unsigned uint32

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

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

      You are visitor 01402520 — GeezerVison does not store the pages you look up.
      Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.