Skip to content

Node 22.23.5 build without the fibers patches, for FedRAMP - #35

Open
jrsells wants to merge 3 commits into
v22.23.5from
jrsells/node-v22.23.5-no-fibers
Open

jrsells wants to merge 3 commits into
v22.23.5from
jrsells/node-v22.23.5-no-fibers

Conversation

@jrsells

@jrsells jrsells commented Nov 14, 2026 •

Copy link
Copy Markdown

Builds Node 22.23.5, the latest Node 22 release, for LunaServer's FedRAMP images, which went back to Node 22 FIPS in Asana/codez#464403. Our Node 22 build is 22.21.1 plus one backported fix (CVE-2026-111497), so it misses the other fixes from the six Node 22 security releases since then: 22.22.0, 22.22.2, 22.23.0, 22.23.2, 22.23.4 and 22.23.5.

The base branch v22.23.5 is upstream's v22.23.5 tag, unchanged. This branch adds three commits:

  • Dockerfiles: Dockerfile.Node22 and Dockerfile.Node22fips from v22.21.1, unchanged. The builds use the same Ubuntu images, g++-10 and configure flags as the 22.21.1 builds, and the FIPS build still links Ubuntu 22.04's OpenSSL 3.0 headers with --shared-openssl.
  • Workflows, verification and staging: from the Node 26 branch (Node 26.13.1 build (RHEL 8 toolchain) for LunaServer #34), which already builds without fibers. The FIPS workflow defaults to Dockerfile.Node22fips. The smoke test expects Node 22's shared-cage pointer compression and Maglev turned off, matching the 22.21.1 builds.
  • A V8 build fix: Node 22 hasn't compiled with --experimental-enable-pointer-compression since 22.22.2 (nodejs/node#62631), which is why our Node 22 build stayed on 22.21.1 and why the v22.23.4 port (Merge v22 patches from v22.21.1 branch #29) failed. A hash-flooding backport made AstRawString::AsArrayIndex() call ReadOnlyHeap::GetReadOnlyRoots(), which only exists with a shared read-only heap, and configure turns that off for pointer-compression builds. The proposed upstream fix (nodejs/node#62664) doesn't compile on V8 12.4. Here, without a shared read-only heap, AsArrayIndex() parses the index from the string's digits, as it already does for longer strings, instead of decoding the seeded cached index. That gives the same result.

It drops every fibers change the v22.21.1 branch carries:

  • the V8 Isolate thread-local storage patch;
  • the src/env.cc change that stopped creating the CppHeap;
  • the realm.js change that exposed internalBinding('util') through process.binding('util');
  • the node-fibers workflow and Dockerfile, Dockerfile.Node20fips and build-local.sh.

codez no longer uses node-fibers or fiber_elimination_utils.ts, the only reader of process.binding('util'), and its Node 26 builds already run without these patches.

The builds derive the version from src/node_version.h, so they publish to new node-v22.23.5-release and node-v22.23.5-fips-release slots. The Node 22 native packages codez already pins stay usable: the build keeps NODE_MODULE_VERSION 127 and the same pointer-compression configuration.

Test plan

All checks ran on linux-arm64, with the FIPS build on FedRAMP's FIPS base image (lunaserver-fips-base), compared with the 22.21.1 builds:

  • Smoke test on 22.21.1: with the Node 22 expectations, it passes on the 22.21.1 standard build on Ubuntu 22.04 and on the 22.21.1 FIPS build on FedRAMP's base image.
  • Workflows: both pass on x64 and arm64, including asana-verify-build.sh, which runs the smoke test on Ubuntu 22.04 and Wolfi.
  • FIPS build on FedRAMP's base image: it passes the smoke test with FIPS mode on. It accepts the 10-byte HMAC keys TOTP uses, with the same digest as 22.21.1. It matches 22.21.1 on all 21 operations in a battery of FIPS-restricted operations.
  • Native packages: codez's Node 22 packages (bcrypt, cld, unix-dgram, @datadog/pprof 5.15.1) load on the standard and FIPS builds, and pprof's heap and CPU profiles work.
  • V8 fix: array-index property keys parse and look up correctly in the main isolate, a new context and a worker. This is the path the fix changes.
  • Node's test/parallel suite: 3,885 passed and 7 failed, against 3,886 and 6 for upstream's official 22.23.5 binary on the same tests. The one extra failure, test-max-old-space-size-percentage, and one extra skip, test-experimental-shared-value-conveyor, come from the 4 GiB pointer-compression heap cage. Upstream CI doesn't build with pointer compression.

Unchanged from v22.21.1, so this build uses the same Ubuntu images, g++-10 and
configure flags as the Node 22 builds LunaServer runs today. The FIPS build still links
the Ubuntu 22.04 OpenSSL 3.0 headers with --shared-openssl.
Ports the build workflows, build verification and staging script from the Node 26
branch (jrsells/node-v26.13.1-rhel8), which already work without fibers.

Compared with the v22.21.1 branch, this leaves out every fibers change:
- the V8 Isolate thread-local storage patch,
- the src/env.cc change that stopped creating the CppHeap,
- the realm.js change that exposed internalBinding('util') through process.binding('util'),
- the node-fibers workflow and Dockerfile, Dockerfile.Node20fips and build-local.sh.

codez no longer uses node-fibers or fiber_elimination_utils.ts, the only reader of
process.binding('util'), and its Node 26 builds already run without these patches.

The smoke test expects Node 22's shared-cage pointer compression and Maglev disabled,
matching the v22.21.1 builds.
Since 22.22.2, AstRawString::AsArrayIndex() decodes cached array indices with
HashSeed(ReadOnlyHeap::GetReadOnlyRoots()), which only exists with V8_SHARED_RO_HEAP.
configure turns the shared read-only heap off for --experimental-enable-pointer-compression
builds, so ours don't compile (nodejs#62631). The proposed upstream fix,
nodejs#62664, calls a GetReadOnlyRoots() that V8 12.4 doesn't have.

Without a shared read-only heap there's no process-wide hash seed to decode the cached
index with, so parse the index from the string's digits, as the function already does
for longer strings. For strings short enough to cache an index, the result is the same.
@jrsells
jrsells force-pushed the jrsells/node-v22.23.5-no-fibers branch from b3bcefb to a4efcff Compare November 15, 2026 00:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

1 participant