Skip to content

upgrade: rebase the Node 26 line onto v26.12.1 with the Android OpenSSL 4.0.3 runtime - #14

Open
fogtape wants to merge 15 commits into
recipe-v26from
upgrade/node26.12.1
Open

fogtape wants to merge 15 commits into
recipe-v26from
upgrade/node26.12.1

Conversation

@fogtape

@fogtape fogtape commented Oct 21, 2026

Copy link
Copy Markdown
Owner

What this does

Upgrades the Node 26 line to the official v26.12.1 security release
(bc2e01dcf6acd5cf7d169b5f26cf89abaaeb41f1) with the mobile version at
26.12.1-0, and lands it on recipe-v26 together with the Android
OpenSSL 4.0.3 line it depends on.

The branch is based on openssl4/node26.12.0, so this PR also carries the 13
commits that are not yet on recipe-v26: the prebuilt static OpenSSL 4.0.3
tree, native ECH/H3 and QUIC on Android, the 16 KB LOAD/RELRO alignment, and
the 26.12.0 upgrade. recipe-v26 is still at 26.11.0-0, while the runtime that
danmu-api-android ships (v26.12.0-0) already comes from that branch — the
line and its documented OpenSSL 4 configuration
(docs/OPENSSL-4.md, docs/VERSION-LINES.md) only converge once this lands.
Say the word if you would rather split it into two PRs and I will retarget.

Why it matters

v26.12.1 is upstream's security release: ten CVEs, four High — tls
non-canonical IP addresses and the IP-normalization regression, dns resolve
null bytes, the http agent data guard, brotli block-switch decoding, zlib ZIP
local headers, permission-model wildcard/realpathSync checks and crypto
snapshot random caches. It also carries c-ares 1.34.9, undici 8.12.2, root
certificates NSS 3.131.1 and the "synchronously load most ES modules" revert.

Android takes OpenSSL from the prebuilt 4.0.3 tree, so this release's bundled
OpenSSL 3.5.9 update does not apply to that path; iOS and the bundled fallback
keep their existing line. The JS/C++ fixes, c-ares and brotli updates apply to
both.

Rebase

All 24 patches apply. Three change, and only in context/line numbers:
common.gypi (v8_embedder_string -node.58), the mobile adjustment in
src/crypto/crypto_context.cc (new upstream includes ahead of the mobile
hunks) and the ECH/H3 patch (lib/internal/tls/wrap.js, lib/tls.js,
src/crypto/crypto_tls.cc context). The mobile hunks themselves are
unchanged, and the OpenSSL 4 ECH/H3 and QUIC patches keep their behaviour.

test-crypto-random-cache-snapshot is excluded on Android and iOS: it builds
and runs snapshots through common/snapshot, which spawns child Node
executables. The other new in-process regressions (tls non-canonical IP and
SPKI blocklist, dns null bytes, http agent pending read, X.509 name
conversion, permission audit realpathSync) stay runnable and the full device
suite confirms them.

Verification

  • A clean reconstruction from a fresh shallow clone of nodejs/node@v26.12.1
    reproduces tree c6b944fa7886345dbf461cc078475f35469959e5, matching
    expected-tree.txt.
  • Local gates pass: upstream-clone (5), flavor/ICU (5), runtime stripping (1),
    mobile toolchains (5), verdict isolation (6), release control, and the
    Android suite coverage check — 4152 runnable cases across 16 shards with no
    gaps or duplicates.
  • Partition check (24 patches / 151 owned paths / 102 fork-only files), curated
    list lint (220 entries), zero workflow files in the product tree, and the
    test-edit audit all pass.

release-ready.txt and release-upstream-snapshot.txt stay empty: this is a
source upgrade, not an armed release. Android/iOS compilation and the device
gates remain for CI; danmu-api-android stays on 26.12.0 until a 26.12.1-0
runtime is published and validated.

26.11.1 is the patch release that followed the reviewed 26.11.0 proposal snapshot. Pin the official tag (364593d0631def13e3043dd84f77ebca2c767ce5), bump the mobile version to 26.11.1-0, and regenerate the series: 21 of 22 patches are byte-identical, and only the upstream-workflow removal patch changes, absorbing the modify/delete conflict on .github/workflows/build-tarball.yml (resolution: deletion, per the patch's intent).

A fresh shallow reconstruction reproduces tree 2a6d2dfd8e605b6eb1a0a2c2c24c48fe92836295 (expected-tree.txt).

Assisted-by: Codex
Upstream Node bundles the OpenSSL 3.5.x line; OpenSSL 4.0 is the first release with ECH (RFC 9849). Build the pinned 4.0.3 release asset with the NDK (static, no-asm, -fPIC) and link it into libnode.so through --shared-openssl behind NODEJS_MOBILE_ANDROID_OPENSSL_DIR; the bundled path and iOS are unchanged. node:quic stays disabled and no ECH API is exposed yet.

- tools/android_openssl.sh builds the SHA-256-verified tarball per ABI.
- android_build.sh wires it in and greps the artifact for the version.
- The Build workflow re-checks every restored artifact and folds the builder script into the libnode cache key.
- docs/OPENSSL-4.md records scope, verification and maintenance.

A fresh shallow reconstruction reproduces tree 70b5331e853ee5c94b9501072dda8758236b9703 (expected-tree.txt).

Assisted-by: Codex
node_js2c (host) failed to link: configure put the external OpenSSL libpath and -lssl/-lcrypto into the global libraries, which gyp applies to host tool links as well, and the host linker cannot use the target ABI's archives.

- android_configure.py now passes only --shared-openssl-includes and exports the library directory through GYP_DEFINES; a post-configure step drops any stray -lcrypto/-lssl from config.gypi's global libraries in case pkg-config added them.
- node.gypi applies -L… -lssl -lcrypto for the node/libnode targets only (node.gypi is not included by host tools; node_mksnapshot is not built on Android).

A fresh shallow reconstruction reproduces tree 5cfd8f0bf17dcca6a7a594dc272f83991a664a02 (expected-tree.txt).

Assisted-by: Codex
config.gypi is a '# Do not edit' banner followed by JSON; json.load() from byte zero crashed every Android leg right after configure. Parse from the first '{' and rewrite while preserving the banner and the layout configure.py itself writes (verified against a synthetic file matching its writer).

A fresh shallow reconstruction reproduces tree 1dd8edc4ccdce79b7a1e7a19b60e4a64aaa1cb60 (expected-tree.txt).

Assisted-by: Codex
configure_library('openssl') put -L…/-lssl/-lcrypto into the global libraries, which gyp applies to every target; nop (a plain test binary) and node_js2c failed to link. Under NODEJS_MOBILE_ANDROID_OPENSSL_DIR, configure.py now adds only the include directory, and node.gypi keeps the link flags for the node/libnode targets. The previous config.gypi post-edit is dropped: it ran after gyp had already consumed the file.

A fresh shallow reconstruction reproduces tree d41435800d43f8de4c6775704f8b477e371f93ee (expected-tree.txt).

Assisted-by: Codex
Pin the official v26.12.0 tag (26e72d85a611e222e3f06025de8a3c496923bacd) and bump the mobile version to 26.12.0-0. All 24 patches apply: 15 are byte-identical and 9 changed only in context/line numbers or in the upstream-workflow removal contents. The OpenSSL 4 ECH/H3 and QUIC patches preserve their behavior.

A clean reconstruction reproduces tree 48d300e (expected-tree.txt). Local recipe tests pass, including 4146 Android suite cases across 16 shards. Android/iOS compilation and device validation remain for CI; danmu-api-android stays on its current runtime until that succeeds.

Leave release-ready.txt and release-upstream-snapshot.txt empty: this is a source upgrade, not an armed release.

Assisted-by: Codex
Pin the official v26.12.1 security tag
(bc2e01dcf6acd5cf7d169b5f26cf89abaaeb41f1) and bump the mobile version to
26.12.1-0. All 24 patches apply; three change, and only in context/line
numbers: common.gypi (v8_embedder_string -node.58), the mobile adjustment in
src/crypto/crypto_context.cc (new upstream includes ahead of the mobile
hunks) and the ECH/H3 patch (lib/internal/tls/wrap.js, lib/tls.js,
src/crypto/crypto_tls.cc context). The mobile hunks themselves are unchanged.

This is upstream's security release for the line: ten CVEs, four High, in
tls non-canonical IP addresses and the IP-normalization regression, dns
resolve null bytes, the http agent data guard, brotli block-switch decoding,
zlib ZIP local headers, permission-model wildcard/realpathSync checks and
crypto snapshot random caches, plus c-ares 1.34.9, undici 8.12.2, root
certificates NSS 3.131.1 and the "synchronously load most ES modules" revert.

Android keeps the prebuilt static OpenSSL 4.0.3 tree with native ECH/H3, so
this release's bundled-OpenSSL 3.5.9 update does not reach the Android
runtime; iOS and the bundled fallback keep their existing line.

test-crypto-random-cache-snapshot is excluded on Android and iOS: it builds
and runs snapshots through common/snapshot, which spawns child Node
executables. The remaining new in-process regressions stay runnable and the
full device suite confirms them.

A clean reconstruction reproduces tree
c6b944fa7886345dbf461cc078475f35469959e5 (expected-tree.txt). Local recipe
tests pass, including 4152 runnable Android suite cases across 16 shards.
Android/iOS compilation and device validation remain for CI;
danmu-api-android stays on 26.12.0 until that succeeds.

Leave release-ready.txt and release-upstream-snapshot.txt empty: this is a
source upgrade, not an armed release.

Assisted-by: Codex

Signed-off-by: fogtape <lilixu3210@gmail.com>
The 26.12 line's first full device suite surfaced three classes.

In-process adaptations, coverage kept:
- test-crypto-x509 runs the malformed-certificate legacy conversion in-process
  on Android/iOS instead of in a child, which an app cannot spawn.
- test-fastutf8stream-flush-mocks keeps every in-process flush/fsync case and
  guards only the case that needs a child with a regular-file stdout.

New upstream tests that cannot run in an embedder (SKIP with the reason in the
.status files): test-bench-cli-ack, test-bench-run-exit-code,
test-common-wpt-allowed-rejections, test-permission-allow-fs-vfs-flags and
sequential/test-benchmark-node-bench-tools spawn child Node executables;
test-sqlite-statement's oversized-string cases outgrow the app heap.

Android QUIC: seven key-update and H3 tests abort inside ngtcp2 with
"conn->state == NGTCP2_CS_POST_HANDSHAKE" in conn_initiate_key_update. The
tests are unchanged by 26.12, so this belongs to the OpenSSL 4 QUIC line and
needs its own investigation; the exclusions carry that reason and 261 of the
268 QUIC tests still run.

A clean reconstruction reproduces tree
55cfa433c72e43f99a49b8ad83ebe62d02cfaffc (expected-tree.txt); the Android
coverage check reports 4139 runnable cases across 16 shards with no gaps.

Assisted-by: Codex
Signed-off-by: fogtape <lilixu3210@gmail.com>

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant