From ca3ae9652da82da5a84f6d181f10210b8af9c7a9 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Tue, 9 Dec 2025 12:59:50 +0000 Subject: [PATCH 01/11] nodejs 24 upgrade --- SPECS/nodejs/nodejs.signatures.json | 8 ++++---- SPECS/nodejs/nodejs.spec | 32 ++++++++++++++--------------- 2 files changed, 20 insertions(+), 20 deletions(-) diff --git a/SPECS/nodejs/nodejs.signatures.json b/SPECS/nodejs/nodejs.signatures.json index 1aae9452d70..f959741983d 100644 --- a/SPECS/nodejs/nodejs.signatures.json +++ b/SPECS/nodejs/nodejs.signatures.json @@ -1,5 +1,5 @@ { - "Signatures": { - "node-v20.14.0.tar.xz": "1f5d3dc55f968f5141410b301303e11612c1c407402683eb3026d722b52fd37e" - } -} + "Signatures": { + "node-v24.11.1.tar.xz": "02bdfec532370eca7ed919478cd6453bdf43b89c7350e6a303adae2958c4ee43" + } +} \ No newline at end of file diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index 6b80ae56ff7..b30b308d55e 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -4,7 +4,7 @@ Summary: A JavaScript runtime built on Chrome's V8 JavaScript engine. Name: nodejs # WARNINGS: MUST check and update the 'npm_version' macro for every version update of this package. # The version of NPM can be found inside the sources under 'deps/npm/package.json'. -Version: 20.14.0 +Version: 24.11.1 Release: 10%{?dist} License: BSD AND MIT AND Public Domain AND NAIST-2003 AND Artistic-2.0 Vendor: Microsoft Corporation @@ -15,21 +15,21 @@ URL: https://github.com/nodejs/node # !!!! because it contains patented algorithms. # !!! => use generate_source_tarball.sh script to create a clean and reproducible source tarball. Source0: https://nodejs.org/download/release/v%{version}/node-v%{version}.tar.xz -Patch0: disable-tlsv1-tlsv1-1.patch -Patch1: CVE-2019-10906.patch -Patch2: CVE-2024-21538.patch -Patch3: CVE-2025-23083.patch -Patch4: CVE-2025-22150.patch -Patch5: CVE-2025-23085.patch -Patch6: CVE-2024-22020.patch -Patch7: CVE-2024-22195.patch -Patch8: CVE-2020-28493.patch -Patch9: CVE-2024-34064.patch -Patch10: CVE-2025-27516.patch -Patch11: CVE-2025-47279.patch -Patch12: CVE-2025-23165.patch -Patch13: CVE-2025-23166.patch -Patch14: CVE-2025-5222.patch +#Patch0: disable-tlsv1-tlsv1-1.patch +#Patch1: CVE-2019-10906.patch +#Patch2: CVE-2024-21538.patch +#Patch3: CVE-2025-23083.patch +#Patch4: CVE-2025-22150.patch +#Patch5: CVE-2025-23085.patch +#Patch6: CVE-2024-22020.patch +#Patch7: CVE-2024-22195.patch +#Patch8: CVE-2020-28493.patch +#Patch9: CVE-2024-34064.patch +#Patch10: CVE-2025-27516.patch +#Patch11: CVE-2025-47279.patch +#Patch12: CVE-2025-23165.patch +#Patch13: CVE-2025-23166.patch +#Patch14: CVE-2025-5222.patch BuildRequires: brotli-devel BuildRequires: c-ares-devel BuildRequires: coreutils >= 8.22 From d1d0d9d9f75bcff0e2bc8c7dbcaf717aed9adce5 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Mon, 22 Dec 2025 18:59:50 +0000 Subject: [PATCH 02/11] Update CVEs and fix for internationalization support --- SPECS/nodejs/CVE-2024-21538.patch | 36 -- SPECS/nodejs/CVE-2024-22020.patch | 46 --- SPECS/nodejs/CVE-2025-22150.patch | 40 --- SPECS/nodejs/CVE-2025-23083.patch | 94 ----- SPECS/nodejs/CVE-2025-23085.patch | 200 ----------- SPECS/nodejs/CVE-2025-23165.patch | 28 -- SPECS/nodejs/CVE-2025-23166.patch | 537 ---------------------------- SPECS/nodejs/CVE-2025-47279.patch | 39 -- SPECS/nodejs/CVE-2025-5222.patch | 164 --------- SPECS/nodejs/btest402.js | 151 ++++++++ SPECS/nodejs/nodejs.signatures.json | 3 + SPECS/nodejs/nodejs.spec | 70 +++- 12 files changed, 207 insertions(+), 1201 deletions(-) delete mode 100644 SPECS/nodejs/CVE-2024-21538.patch delete mode 100644 SPECS/nodejs/CVE-2024-22020.patch delete mode 100644 SPECS/nodejs/CVE-2025-22150.patch delete mode 100644 SPECS/nodejs/CVE-2025-23083.patch delete mode 100644 SPECS/nodejs/CVE-2025-23085.patch delete mode 100644 SPECS/nodejs/CVE-2025-23165.patch delete mode 100644 SPECS/nodejs/CVE-2025-23166.patch delete mode 100644 SPECS/nodejs/CVE-2025-47279.patch delete mode 100644 SPECS/nodejs/CVE-2025-5222.patch create mode 100644 SPECS/nodejs/btest402.js diff --git a/SPECS/nodejs/CVE-2024-21538.patch b/SPECS/nodejs/CVE-2024-21538.patch deleted file mode 100644 index 7620a62ff46..00000000000 --- a/SPECS/nodejs/CVE-2024-21538.patch +++ /dev/null @@ -1,36 +0,0 @@ -From ea1368b332cebba727436bf4dddebb0c5d7a9d5b Mon Sep 17 00:00:00 2001 -From: bala -Date: Tue, 19 Nov 2024 12:03:43 +0000 -Subject: [PATCH] Vendor patch applied to fix CVE-2024-21538 - ---- - deps/npm/node_modules/cross-spawn/lib/util/escape.js | 6 ++++-- - 1 file changed, 4 insertions(+), 2 deletions(-) - -diff --git a/deps/npm/node_modules/cross-spawn/lib/util/escape.js b/deps/npm/node_modules/cross-spawn/lib/util/escape.js -index b0bb84c..e4804b9 100644 ---- a/deps/npm/node_modules/cross-spawn/lib/util/escape.js -+++ b/deps/npm/node_modules/cross-spawn/lib/util/escape.js -@@ -15,15 +15,17 @@ function escapeArgument(arg, doubleEscapeMetaChars) { - arg = `${arg}`; - - // Algorithm below is based on https://qntm.org/cmd -+ // It's slightly altered to disable JS backtracking to avoid hanging on specially crafted input -+ // Please see https://github.com/moxystudio/node-cross-spawn/pull/160 for more information - - // Sequence of backslashes followed by a double quote: - // double up all the backslashes and escape the double quote -- arg = arg.replace(/(\\*)"/g, '$1$1\\"'); -+ arg = arg.replace(/(?=\\*?)"/g, '$1$1\\"'); - - // Sequence of backslashes followed by the end of the string - // (which will become a double quote later): - // double up all the backslashes -- arg = arg.replace(/(\\*)$/, '$1$1'); -+ arg = arg.replace(/(?=\\*?)$/, '$1$1'); - - // All other backslashes occur literally - --- -2.39.4 - diff --git a/SPECS/nodejs/CVE-2024-22020.patch b/SPECS/nodejs/CVE-2024-22020.patch deleted file mode 100644 index 563ea2a6f4a..00000000000 --- a/SPECS/nodejs/CVE-2024-22020.patch +++ /dev/null @@ -1,46 +0,0 @@ -From 9defa3bb7532c1b7f3ea51aed9989954382ea5a9 Mon Sep 17 00:00:00 2001 -From: Kanishk-Bansal -Date: Tue, 11 Feb 2025 17:25:37 +0000 -Subject: [PATCH] Fix CVE-2024-22020 - ---- - lib/internal/modules/esm/resolve.js | 16 +++++++++++++++- - 1 file changed, 15 insertions(+), 1 deletion(-) - -diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js -index b56ad6cc..8cd08de8 100644 ---- a/lib/internal/modules/esm/resolve.js -+++ b/lib/internal/modules/esm/resolve.js -@@ -1108,6 +1108,17 @@ function defaultResolve(specifier, context = {}) { - - // Avoid accessing the `protocol` property due to the lazy getters. - protocol = parsed.protocol; -+ -+ if (protocol === 'data:' && -+ parsedParentURL.protocol !== 'file:' && -+ experimentalNetworkImports) { -+ throw new ERR_NETWORK_IMPORT_DISALLOWED( -+ specifier, -+ parsedParentURL, -+ 'import data: from a non file: is not allowed', -+ ); -+ } -+ - if (protocol === 'data:' || - (experimentalNetworkImports && - ( -@@ -1118,7 +1129,10 @@ function defaultResolve(specifier, context = {}) { - ) { - return { __proto__: null, url: parsed.href }; - } -- } catch { -+ } catch (e) { -+ if (e?.code === 'ERR_NETWORK_IMPORT_DISALLOWED') { -+ throw e; -+ } - // Ignore exception - } - --- -2.45.2 - diff --git a/SPECS/nodejs/CVE-2025-22150.patch b/SPECS/nodejs/CVE-2025-22150.patch deleted file mode 100644 index 9634c621992..00000000000 --- a/SPECS/nodejs/CVE-2025-22150.patch +++ /dev/null @@ -1,40 +0,0 @@ -From 7a5aff9d9e6b6b541f7528cedb9bcf2046289f1a Mon Sep 17 00:00:00 2001 -From: Kanishk Bansal -Date: Wed, 5 Feb 2025 12:14:46 +0000 -Subject: [PATCH] Address CVE-2025-22150 - ---- - deps/undici/src/lib/web/fetch/body.js | 10 +++++++++- - 1 file changed, 9 insertions(+), 1 deletion(-) - -diff --git a/deps/undici/src/lib/web/fetch/body.js b/deps/undici/src/lib/web/fetch/body.js -index 26cce5f3..594620b5 100644 ---- a/deps/undici/src/lib/web/fetch/body.js -+++ b/deps/undici/src/lib/web/fetch/body.js -@@ -20,6 +20,14 @@ const { isErrored } = require('../../core/util') - const { isArrayBuffer } = require('node:util/types') - const { serializeAMimeType } = require('./data-url') - const { multipartFormDataParser } = require('./formdata-parser') -+let random -+ -+try { -+ const crypto = require('node:crypto') -+ random = (max) => crypto.randomInt(0, max) -+} catch { -+ random = (max) => Math.floor(Math.random(max)) -+} - - const textEncoder = new TextEncoder() - -@@ -100,7 +108,7 @@ function extractBody (object, keepalive = false) { - // Set source to a copy of the bytes held by object. - source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) - } else if (util.isFormDataLike(object)) { -- const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` -+ const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, '0')}` - const prefix = `--${boundary}\r\nContent-Disposition: form-data` - - /*! formdata-polyfill. MIT License. Jimmy Wärting */ --- -2.43.0 - diff --git a/SPECS/nodejs/CVE-2025-23083.patch b/SPECS/nodejs/CVE-2025-23083.patch deleted file mode 100644 index 36adf8dabd4..00000000000 --- a/SPECS/nodejs/CVE-2025-23083.patch +++ /dev/null @@ -1,94 +0,0 @@ -From 389f239a282de04651cebdc99bc0af5d19aa955d Mon Sep 17 00:00:00 2001 -From: RafaelGSS -Date: Tue, 27 Aug 2024 18:00:12 -0300 -Subject: [PATCH] src,loader,permission: throw on InternalWorker use - -Previously this PR it was expected that InternalWorker -usage doesn't require the --allow-worker when the permission -model is enabled. This, however, exposes a vulnerability -whenever the instance gets accessed by the user. For example -through diagnostics_channel.subscribe('worker_threads') - -PR-URL: https://github.com/nodejs-private/node-private/pull/652 -Refs: https://hackerone.com/reports/2575105 -CVE-ID: CVE-2025-23083 ---- - src/node_worker.cc | 6 ++---- - test/es-module/test-esm-loader-hooks.mjs | 8 ++++---- - .../test-permission-dc-worker-threads.js | 19 +++++++++++++++++++ - 3 files changed, 25 insertions(+), 8 deletions(-) - create mode 100644 test/parallel/test-permission-dc-worker-threads.js - -diff --git a/src/node_worker.cc b/src/node_worker.cc -index 196eb3bc..31268115 100644 ---- a/src/node_worker.cc -+++ b/src/node_worker.cc -@@ -484,12 +484,10 @@ Worker::~Worker() { - - void Worker::New(const FunctionCallbackInfo& args) { - Environment* env = Environment::GetCurrent(args); -+ THROW_IF_INSUFFICIENT_PERMISSIONS( -+ env, permission::PermissionScope::kWorkerThreads, ""); - auto is_internal = args[5]; - CHECK(is_internal->IsBoolean()); -- if (is_internal->IsFalse()) { -- THROW_IF_INSUFFICIENT_PERMISSIONS( -- env, permission::PermissionScope::kWorkerThreads, ""); -- } - Isolate* isolate = args.GetIsolate(); - - CHECK(args.IsConstructCall()); -diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs -index 8e616c0d..225ab26a 100644 ---- a/test/es-module/test-esm-loader-hooks.mjs -+++ b/test/es-module/test-esm-loader-hooks.mjs -@@ -154,7 +154,7 @@ describe('Loader hooks', { concurrency: true }, () => { - }); - }); - -- it('should work without worker permission', async () => { -+ it('should not work without worker permission', async () => { - const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ - '--no-warnings', - '--experimental-permission', -@@ -165,9 +165,9 @@ describe('Loader hooks', { concurrency: true }, () => { - fixtures.path('es-modules/esm-top-level-await.mjs'), - ]); - -- assert.strictEqual(stderr, ''); -- assert.match(stdout, /^1\r?\n2\r?\n$/); -- assert.strictEqual(code, 0); -+ assert.match(stderr, /Error: Access to this API has been restricted/); -+ assert.strictEqual(stdout, ''); -+ assert.strictEqual(code, 1); - assert.strictEqual(signal, null); - }); - -diff --git a/test/parallel/test-permission-dc-worker-threads.js b/test/parallel/test-permission-dc-worker-threads.js -new file mode 100644 -index 00000000..73cbf029 ---- /dev/null -+++ b/test/parallel/test-permission-dc-worker-threads.js -@@ -0,0 +1,19 @@ -+// Flags: --experimental-permission --allow-fs-read=* --experimental-test-module-mocks -+'use strict'; -+ -+const common = require('../common'); -+const assert = require('node:assert'); -+ -+{ -+ const diagnostics_channel = require('node:diagnostics_channel'); -+ diagnostics_channel.subscribe('worker_threads', common.mustNotCall()); -+ const { mock } = require('node:test'); -+ -+ // Module mocking should throw instead of posting to worker_threads dc -+ assert.throws(() => { -+ mock.module('node:path'); -+ }, common.expectsError({ -+ code: 'ERR_ACCESS_DENIED', -+ permission: 'WorkerThreads', -+ })); -+} --- -2.25.1 - diff --git a/SPECS/nodejs/CVE-2025-23085.patch b/SPECS/nodejs/CVE-2025-23085.patch deleted file mode 100644 index e87cd44440a..00000000000 --- a/SPECS/nodejs/CVE-2025-23085.patch +++ /dev/null @@ -1,200 +0,0 @@ -From ea5045019e58f1d5780df3fff484d2010fd38c9d Mon Sep 17 00:00:00 2001 -From: Kanishk-Bansal -Date: Tue, 11 Feb 2025 16:05:07 +0000 -Subject: [PATCH] fix CVE-2025-23085 for 3.0 - ---- - lib/internal/http2/core.js | 15 ++++++-- - src/node_http2.cc | 36 ++++++++++++++++--- - ...2-connect-method-extended-cant-turn-off.js | 6 ++++ - ...-http2-options-max-headers-block-length.js | 4 ++- - ...tp2-options-max-headers-exceeds-nghttp2.js | 4 ++- - 5 files changed, 55 insertions(+), 10 deletions(-) - -diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js -index 761e8713..0324432f 100644 ---- a/lib/internal/http2/core.js -+++ b/lib/internal/http2/core.js -@@ -617,11 +617,20 @@ function onFrameError(id, type, code) { - return; - debugSessionObj(session, 'error sending frame type %d on stream %d, code: %d', - type, id, code); -- const emitter = session[kState].streams.get(id) || session; -+ -+ const stream = session[kState].streams.get(id); -+ const emitter = stream || session; - emitter[kUpdateTimer](); - emitter.emit('frameError', type, code, id); -- session[kState].streams.get(id).close(code); -- session.close(); -+ -+ // When a frameError happens is not uncommon that a pending GOAWAY -+ // package from nghttp2 is on flight with a correct error code. -+ // We schedule it using setImmediate to give some time for that -+ // package to arrive. -+ setImmediate(() => { -+ stream?.close(code); -+ session.close(); -+ }); - } - - function onAltSvc(stream, origin, alt) { -diff --git a/src/node_http2.cc b/src/node_http2.cc -index eada4081..28dfe532 100644 ---- a/src/node_http2.cc -+++ b/src/node_http2.cc -@@ -844,6 +844,7 @@ bool Http2Session::CanAddStream() { - } - - void Http2Session::AddStream(Http2Stream* stream) { -+ Debug(this, "Adding stream: %d", stream->id()); - CHECK_GE(++statistics_.stream_count, 0); - streams_[stream->id()] = BaseObjectPtr(stream); - size_t size = streams_.size(); -@@ -854,6 +855,7 @@ void Http2Session::AddStream(Http2Stream* stream) { - - - BaseObjectPtr Http2Session::RemoveStream(int32_t id) { -+ Debug(this, "Removing stream: %d", id); - BaseObjectPtr stream; - if (streams_.empty()) - return stream; -@@ -1030,6 +1032,7 @@ int Http2Session::OnHeaderCallback(nghttp2_session* handle, - if (UNLIKELY(!stream)) - return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; - -+ Debug(session, "handling header key/pair for stream %d", id); - // If the stream has already been destroyed, ignore. - if (!stream->is_destroyed() && !stream->AddHeader(name, value, flags)) { - // This will only happen if the connected peer sends us more -@@ -1099,9 +1102,21 @@ int Http2Session::OnInvalidFrame(nghttp2_session* handle, - return 1; - } - -- // If the error is fatal or if error code is ERR_STREAM_CLOSED... emit error -+ // If the error is fatal or if error code is one of the following -+ // we emit and error: -+ // -+ // ERR_STREAM_CLOSED: An invalid frame has been received in a closed stream. -+ // -+ // ERR_PROTO: The RFC 7540 specifies: -+ // "An endpoint that encounters a connection error SHOULD first send a GOAWAY -+ // frame (Section 6.8) with the stream identifier of the last stream that it -+ // successfully received from its peer. -+ // The GOAWAY frame includes an error code that indicates the type of error" -+ // The GOAWAY frame is already sent by nghttp2. We emit the error -+ // to liberate the Http2Session to destroy. - if (nghttp2_is_fatal(lib_error_code) || -- lib_error_code == NGHTTP2_ERR_STREAM_CLOSED) { -+ lib_error_code == NGHTTP2_ERR_STREAM_CLOSED || -+ lib_error_code == NGHTTP2_ERR_PROTO) { - Environment* env = session->env(); - Isolate* isolate = env->isolate(); - HandleScope scope(isolate); -@@ -1164,7 +1179,6 @@ int Http2Session::OnFrameNotSent(nghttp2_session* handle, - Debug(session, "frame type %d was not sent, code: %d", - frame->hd.type, error_code); - -- // Do not report if the frame was not sent due to the session closing - if (error_code == NGHTTP2_ERR_SESSION_CLOSING || - error_code == NGHTTP2_ERR_STREAM_CLOSED || - error_code == NGHTTP2_ERR_STREAM_CLOSING) { -@@ -1173,7 +1187,15 @@ int Http2Session::OnFrameNotSent(nghttp2_session* handle, - // to destroy the session completely. - // Further information see: https://github.com/nodejs/node/issues/35233 - session->DecrefHeaders(frame); -- return 0; -+ // Currently, nghttp2 doesn't not inform us when is the best -+ // time to call session.close(). It relies on a closing connection -+ // from peer. If that doesn't happen, the nghttp2_session will be -+ // closed but the Http2Session will still be up causing a memory leak. -+ // Therefore, if the GOAWAY frame couldn't be send due to -+ // ERR_SESSION_CLOSING we should force close from our side. -+ if (frame->hd.type != 0x03) { -+ return 0; -+ } - } - - Isolate* isolate = env->isolate(); -@@ -1239,12 +1261,15 @@ int Http2Session::OnStreamClose(nghttp2_session* handle, - // ignore these. If this callback was not provided, nghttp2 would handle - // invalid headers strictly and would shut down the stream. We are intentionally - // being more lenient here although we may want to revisit this choice later. --int Http2Session::OnInvalidHeader(nghttp2_session* session, -+int Http2Session::OnInvalidHeader(nghttp2_session* handle, - const nghttp2_frame* frame, - nghttp2_rcbuf* name, - nghttp2_rcbuf* value, - uint8_t flags, - void* user_data) { -+ Http2Session* session = static_cast(user_data); -+ int32_t id = GetFrameID(frame); -+ Debug(session, "invalid header received for stream %d", id); - // Ignore invalid header fields by default. - return 0; - } -@@ -1638,6 +1663,7 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) { - - // Called by OnFrameReceived when a complete SETTINGS frame has been received. - void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) { -+ Debug(this, "handling settings frame"); - bool ack = frame->hd.flags & NGHTTP2_FLAG_ACK; - if (!ack) { - js_fields_->bitfield &= ~(1 << kSessionRemoteSettingsIsUpToDate); -diff --git a/test/parallel/test-http2-connect-method-extended-cant-turn-off.js b/test/parallel/test-http2-connect-method-extended-cant-turn-off.js -index f4d033ef..456aa1ce 100644 ---- a/test/parallel/test-http2-connect-method-extended-cant-turn-off.js -+++ b/test/parallel/test-http2-connect-method-extended-cant-turn-off.js -@@ -27,4 +27,10 @@ server.listen(0, common.mustCall(() => { - server.close(); - })); - })); -+ -+ client.on('error', common.expectsError({ -+ code: 'ERR_HTTP2_ERROR', -+ name: 'Error', -+ message: 'Protocol error' -+ })); - })); -diff --git a/test/parallel/test-http2-options-max-headers-block-length.js b/test/parallel/test-http2-options-max-headers-block-length.js -index af1cc6f9..15b142ac 100644 ---- a/test/parallel/test-http2-options-max-headers-block-length.js -+++ b/test/parallel/test-http2-options-max-headers-block-length.js -@@ -35,9 +35,11 @@ server.listen(0, common.mustCall(() => { - assert.strictEqual(code, h2.constants.NGHTTP2_FRAME_SIZE_ERROR); - })); - -+ // NGHTTP2 will automatically send the NGHTTP2_REFUSED_STREAM with -+ // the GOAWAY frame. - req.on('error', common.expectsError({ - code: 'ERR_HTTP2_STREAM_ERROR', - name: 'Error', -- message: 'Stream closed with error code NGHTTP2_FRAME_SIZE_ERROR' -+ message: 'Stream closed with error code NGHTTP2_REFUSED_STREAM' - })); - })); -diff --git a/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js b/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js -index df3aefff..7767dbbc 100644 ---- a/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js -+++ b/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js -@@ -59,6 +59,9 @@ server.listen(0, common.mustCall(() => { - 'session', - common.mustCall((session) => { - assert.strictEqual(session instanceof ServerHttp2Session, true); -+ session.on('close', common.mustCall(() => { -+ server.close(); -+ })); - }), - ); - server.on( -@@ -80,7 +83,6 @@ server.listen(0, common.mustCall(() => { - assert.strictEqual(err.name, 'Error'); - assert.strictEqual(err.message, 'Session closed with error code 9'); - assert.strictEqual(session instanceof ServerHttp2Session, true); -- server.close(); - }), - ); - --- -2.45.2 - diff --git a/SPECS/nodejs/CVE-2025-23165.patch b/SPECS/nodejs/CVE-2025-23165.patch deleted file mode 100644 index da41f64457f..00000000000 --- a/SPECS/nodejs/CVE-2025-23165.patch +++ /dev/null @@ -1,28 +0,0 @@ -From 3badbd012233828132ec938253ed40a7854fd65c Mon Sep 17 00:00:00 2001 -From: Aninda -Date: Sat, 24 May 2025 11:03:53 -0400 -Subject: [PATCH] Address CVE-2025-23165 -Upstream Patch Reference: https://github.com/nodejs/node/commit/9e13bf0a81e15c7b3a9f1826dccbcea991d7e63a - ---- - src/node_file.cc | 2 +- - 1 file changed, 1 insertion(+), 1 deletion(-) - -diff --git a/src/node_file.cc b/src/node_file.cc -index 0ec5c6f4..ba69879b 100644 ---- a/src/node_file.cc -+++ b/src/node_file.cc -@@ -2609,9 +2609,9 @@ static void ReadFileUtf8(const FunctionCallbackInfo& args) { - FS_SYNC_TRACE_END(open); - if (req.result < 0) { - uv_fs_req_cleanup(&req); -- // req will be cleaned up by scope leave. - return env->ThrowUVException(req.result, "open", nullptr, path.out()); - } -+ uv_fs_req_cleanup(&req); - } - - auto defer_close = OnScopeLeave([file, is_fd, &req]() { --- -2.34.1 - diff --git a/SPECS/nodejs/CVE-2025-23166.patch b/SPECS/nodejs/CVE-2025-23166.patch deleted file mode 100644 index 467bda09154..00000000000 --- a/SPECS/nodejs/CVE-2025-23166.patch +++ /dev/null @@ -1,537 +0,0 @@ -From cca703fb8440504e580a92256a8f16ca0e38a08e Mon Sep 17 00:00:00 2001 -From: Aninda -Date: Sat, 24 May 2025 10:33:47 -0400 -Subject: [PATCH] Address CVE-2025-23166 -Upstream Patch Reference: https://github.com/nodejs/node/commit/6c57465920cf1b981a63031e71b1e4a73bf9beaa - ---- - src/crypto/crypto_dh.cc | 8 +++--- - src/crypto/crypto_dh.h | 8 +++--- - src/crypto/crypto_ec.cc | 3 +- - src/crypto/crypto_ec.h | 8 +++--- - src/crypto/crypto_hash.cc | 8 +++--- - src/crypto/crypto_hash.h | 8 +++--- - src/crypto/crypto_hkdf.cc | 8 +++--- - src/crypto/crypto_hkdf.h | 8 +++--- - src/crypto/crypto_hmac.cc | 8 +++--- - src/crypto/crypto_hmac.h | 8 +++--- - src/crypto/crypto_pbkdf2.cc | 8 +++--- - src/crypto/crypto_pbkdf2.h | 8 +++--- - src/crypto/crypto_random.cc | 20 ++++++------- - src/crypto/crypto_random.h | 19 +++++++------ - src/crypto/crypto_scrypt.cc | 8 +++--- - src/crypto/crypto_scrypt.h | 8 +++--- - src/crypto/crypto_sig.cc | 28 +++++++++++-------- - src/crypto/crypto_sig.h | 8 +++--- - src/crypto/crypto_util.h | 3 +- - .../parallel/test-crypto-async-sign-verify.js | 26 +++++++++++++++++ - 20 files changed, 122 insertions(+), 89 deletions(-) - -diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc -index b4447102..7c984652 100644 ---- a/src/crypto/crypto_dh.cc -+++ b/src/crypto/crypto_dh.cc -@@ -705,10 +705,10 @@ Maybe DHBitsTraits::EncodeOutput( - return Just(!result->IsEmpty()); - } - --bool DHBitsTraits::DeriveBits( -- Environment* env, -- const DHBitsConfig& params, -- ByteSource* out) { -+bool DHBitsTraits::DeriveBits(Environment* env, -+ const DHBitsConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - *out = StatelessDiffieHellmanThreadsafe( - params.private_key->GetAsymmetricKey(), - params.public_key->GetAsymmetricKey()); -diff --git a/src/crypto/crypto_dh.h b/src/crypto/crypto_dh.h -index ec12548d..f7c4b675 100644 ---- a/src/crypto/crypto_dh.h -+++ b/src/crypto/crypto_dh.h -@@ -131,10 +131,10 @@ struct DHBitsTraits final { - unsigned int offset, - DHBitsConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const DHBitsConfig& params, -- ByteSource* out_); -+ static bool DeriveBits(Environment* env, -+ const DHBitsConfig& params, -+ ByteSource* out_, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc -index 860d5048..356e21f1 100644 ---- a/src/crypto/crypto_ec.cc -+++ b/src/crypto/crypto_ec.cc -@@ -481,7 +481,8 @@ Maybe ECDHBitsTraits::AdditionalConfig( - - bool ECDHBitsTraits::DeriveBits(Environment* env, - const ECDHBitsConfig& params, -- ByteSource* out) { -+ ByteSource* out, -+ CryptoJobMode mode) { - size_t len = 0; - ManagedEVPPKey m_privkey = params.private_->GetAsymmetricKey(); - ManagedEVPPKey m_pubkey = params.public_->GetAsymmetricKey(); -diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h -index f9570bd4..a6bd48d4 100644 ---- a/src/crypto/crypto_ec.h -+++ b/src/crypto/crypto_ec.h -@@ -77,10 +77,10 @@ struct ECDHBitsTraits final { - unsigned int offset, - ECDHBitsConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const ECDHBitsConfig& params, -- ByteSource* out_); -+ static bool DeriveBits(Environment* env, -+ const ECDHBitsConfig& params, -+ ByteSource* out_, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc -index 46086018..7d974d3d 100644 ---- a/src/crypto/crypto_hash.cc -+++ b/src/crypto/crypto_hash.cc -@@ -501,10 +501,10 @@ Maybe HashTraits::AdditionalConfig( - return Just(true); - } - --bool HashTraits::DeriveBits( -- Environment* env, -- const HashConfig& params, -- ByteSource* out) { -+bool HashTraits::DeriveBits(Environment* env, -+ const HashConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - EVPMDCtxPointer ctx(EVP_MD_CTX_new()); - - if (UNLIKELY(!ctx || -diff --git a/src/crypto/crypto_hash.h b/src/crypto/crypto_hash.h -index 07e3a2ae..0ea2114f 100644 ---- a/src/crypto/crypto_hash.h -+++ b/src/crypto/crypto_hash.h -@@ -70,10 +70,10 @@ struct HashTraits final { - unsigned int offset, - HashConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const HashConfig& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const HashConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_hkdf.cc b/src/crypto/crypto_hkdf.cc -index 0dd9b424..526be1d0 100644 ---- a/src/crypto/crypto_hkdf.cc -+++ b/src/crypto/crypto_hkdf.cc -@@ -100,10 +100,10 @@ Maybe HKDFTraits::AdditionalConfig( - return Just(true); - } - --bool HKDFTraits::DeriveBits( -- Environment* env, -- const HKDFConfig& params, -- ByteSource* out) { -+bool HKDFTraits::DeriveBits(Environment* env, -+ const HKDFConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - EVPKeyCtxPointer ctx = - EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr)); - if (!ctx || !EVP_PKEY_derive_init(ctx.get()) || -diff --git a/src/crypto/crypto_hkdf.h b/src/crypto/crypto_hkdf.h -index c4a537ce..acd2b670 100644 ---- a/src/crypto/crypto_hkdf.h -+++ b/src/crypto/crypto_hkdf.h -@@ -42,10 +42,10 @@ struct HKDFTraits final { - unsigned int offset, - HKDFConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const HKDFConfig& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const HKDFConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_hmac.cc b/src/crypto/crypto_hmac.cc -index b101d5c7..5d81a60a 100644 ---- a/src/crypto/crypto_hmac.cc -+++ b/src/crypto/crypto_hmac.cc -@@ -220,10 +220,10 @@ Maybe HmacTraits::AdditionalConfig( - return Just(true); - } - --bool HmacTraits::DeriveBits( -- Environment* env, -- const HmacConfig& params, -- ByteSource* out) { -+bool HmacTraits::DeriveBits(Environment* env, -+ const HmacConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - HMACCtxPointer ctx(HMAC_CTX_new()); - - if (!ctx || -diff --git a/src/crypto/crypto_hmac.h b/src/crypto/crypto_hmac.h -index c80cc36f..dd490f05 100644 ---- a/src/crypto/crypto_hmac.h -+++ b/src/crypto/crypto_hmac.h -@@ -73,10 +73,10 @@ struct HmacTraits final { - unsigned int offset, - HmacConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const HmacConfig& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const HmacConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_pbkdf2.cc b/src/crypto/crypto_pbkdf2.cc -index 963d0db6..f6d37dad 100644 ---- a/src/crypto/crypto_pbkdf2.cc -+++ b/src/crypto/crypto_pbkdf2.cc -@@ -111,10 +111,10 @@ Maybe PBKDF2Traits::AdditionalConfig( - return Just(true); - } - --bool PBKDF2Traits::DeriveBits( -- Environment* env, -- const PBKDF2Config& params, -- ByteSource* out) { -+bool PBKDF2Traits::DeriveBits(Environment* env, -+ const PBKDF2Config& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - ByteSource::Builder buf(params.length); - - // Both pass and salt may be zero length here. -diff --git a/src/crypto/crypto_pbkdf2.h b/src/crypto/crypto_pbkdf2.h -index 6fda7cd3..11ffad78 100644 ---- a/src/crypto/crypto_pbkdf2.h -+++ b/src/crypto/crypto_pbkdf2.h -@@ -55,10 +55,10 @@ struct PBKDF2Traits final { - unsigned int offset, - PBKDF2Config* params); - -- static bool DeriveBits( -- Environment* env, -- const PBKDF2Config& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const PBKDF2Config& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc -index 48154df7..03bdcd5c 100644 ---- a/src/crypto/crypto_random.cc -+++ b/src/crypto/crypto_random.cc -@@ -56,10 +56,10 @@ Maybe RandomBytesTraits::AdditionalConfig( - return Just(true); - } - --bool RandomBytesTraits::DeriveBits( -- Environment* env, -- const RandomBytesConfig& params, -- ByteSource* unused) { -+bool RandomBytesTraits::DeriveBits(Environment* env, -+ const RandomBytesConfig& params, -+ ByteSource* unused, -+ CryptoJobMode mode) { - return CSPRNG(params.buffer, params.size).is_ok(); - } - -@@ -151,7 +151,8 @@ Maybe RandomPrimeTraits::AdditionalConfig( - - bool RandomPrimeTraits::DeriveBits(Environment* env, - const RandomPrimeConfig& params, -- ByteSource* unused) { -+ ByteSource* unused, -+ CryptoJobMode mode) { - // BN_generate_prime_ex() calls RAND_bytes_ex() internally. - // Make sure the CSPRNG is properly seeded. - CHECK(CSPRNG(nullptr, 0).is_ok()); -@@ -194,11 +195,10 @@ Maybe CheckPrimeTraits::AdditionalConfig( - return Just(true); - } - --bool CheckPrimeTraits::DeriveBits( -- Environment* env, -- const CheckPrimeConfig& params, -- ByteSource* out) { -- -+bool CheckPrimeTraits::DeriveBits(Environment* env, -+ const CheckPrimeConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - BignumCtxPointer ctx(BN_CTX_new()); - - int ret = BN_is_prime_ex( -diff --git a/src/crypto/crypto_random.h b/src/crypto/crypto_random.h -index a2807ed6..b673cbbf 100644 ---- a/src/crypto/crypto_random.h -+++ b/src/crypto/crypto_random.h -@@ -32,10 +32,10 @@ struct RandomBytesTraits final { - unsigned int offset, - RandomBytesConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const RandomBytesConfig& params, -- ByteSource* out_); -+ static bool DeriveBits(Environment* env, -+ const RandomBytesConfig& params, -+ ByteSource* out_, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -@@ -72,7 +72,8 @@ struct RandomPrimeTraits final { - static bool DeriveBits( - Environment* env, - const RandomPrimeConfig& params, -- ByteSource* out_); -+ ByteSource* out_, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -@@ -105,10 +106,10 @@ struct CheckPrimeTraits final { - unsigned int offset, - CheckPrimeConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const CheckPrimeConfig& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const CheckPrimeConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_scrypt.cc b/src/crypto/crypto_scrypt.cc -index 4dae07f1..99a6a0e7 100644 ---- a/src/crypto/crypto_scrypt.cc -+++ b/src/crypto/crypto_scrypt.cc -@@ -114,10 +114,10 @@ Maybe ScryptTraits::AdditionalConfig( - return Just(true); - } - --bool ScryptTraits::DeriveBits( -- Environment* env, -- const ScryptConfig& params, -- ByteSource* out) { -+bool ScryptTraits::DeriveBits(Environment* env, -+ const ScryptConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode) { - ByteSource::Builder buf(params.length); - - // Both the pass and salt may be zero-length at this point -diff --git a/src/crypto/crypto_scrypt.h b/src/crypto/crypto_scrypt.h -index 3d185637..9ea9d75d 100644 ---- a/src/crypto/crypto_scrypt.h -+++ b/src/crypto/crypto_scrypt.h -@@ -57,10 +57,10 @@ struct ScryptTraits final { - unsigned int offset, - ScryptConfig* params); - -- static bool DeriveBits( -- Environment* env, -- const ScryptConfig& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const ScryptConfig& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc -index ab020efb..b84fd3b7 100644 ---- a/src/crypto/crypto_sig.cc -+++ b/src/crypto/crypto_sig.cc -@@ -706,11 +706,11 @@ Maybe SignTraits::AdditionalConfig( - return Just(true); - } - --bool SignTraits::DeriveBits( -- Environment* env, -- const SignConfiguration& params, -- ByteSource* out) { -- ClearErrorOnReturn clear_error_on_return; -+bool SignTraits::DeriveBits(Environment* env, -+ const SignConfiguration& params, -+ ByteSource* out, -+ CryptoJobMode mode) { -+ bool can_throw = mode == CryptoJobMode::kCryptoJobSync; - EVPMDCtxPointer context(EVP_MD_CTX_new()); - EVP_PKEY_CTX* ctx = nullptr; - -@@ -722,7 +722,7 @@ bool SignTraits::DeriveBits( - params.digest, - nullptr, - params.key.get())) { -- crypto::CheckThrow(env, SignBase::Error::kSignInit); -+ if (can_throw) crypto::CheckThrow(env, SignBase::Error::kSignInit); - return false; - } - break; -@@ -733,7 +733,7 @@ bool SignTraits::DeriveBits( - params.digest, - nullptr, - params.key.get())) { -- crypto::CheckThrow(env, SignBase::Error::kSignInit); -+ if (can_throw) crypto::CheckThrow(env, SignBase::Error::kSignInit); - return false; - } - break; -@@ -751,7 +751,7 @@ bool SignTraits::DeriveBits( - ctx, - padding, - salt_length)) { -- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); -+ if (can_throw) crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); - return false; - } - -@@ -765,7 +765,8 @@ bool SignTraits::DeriveBits( - &len, - params.data.data(), - params.data.size())) { -- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); -+ if (can_throw) -+ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); - return false; - } - ByteSource::Builder buf(len); -@@ -774,7 +775,8 @@ bool SignTraits::DeriveBits( - &len, - params.data.data(), - params.data.size())) { -- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); -+ if (can_throw) -+ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); - return false; - } - *out = std::move(buf).release(len); -@@ -785,13 +787,15 @@ bool SignTraits::DeriveBits( - params.data.data(), - params.data.size()) || - !EVP_DigestSignFinal(context.get(), nullptr, &len)) { -- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); -+ if (can_throw) -+ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); - return false; - } - ByteSource::Builder buf(len); - if (!EVP_DigestSignFinal( - context.get(), buf.data(), &len)) { -- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); -+ if (can_throw) -+ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); - return false; - } - -diff --git a/src/crypto/crypto_sig.h b/src/crypto/crypto_sig.h -index 63320147..3b2801fa 100644 ---- a/src/crypto/crypto_sig.h -+++ b/src/crypto/crypto_sig.h -@@ -147,10 +147,10 @@ struct SignTraits final { - unsigned int offset, - SignConfiguration* params); - -- static bool DeriveBits( -- Environment* env, -- const SignConfiguration& params, -- ByteSource* out); -+ static bool DeriveBits(Environment* env, -+ const SignConfiguration& params, -+ ByteSource* out, -+ CryptoJobMode mode); - - static v8::Maybe EncodeOutput( - Environment* env, -diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h -index 0ae2946e..260df59d 100644 ---- a/src/crypto/crypto_util.h -+++ b/src/crypto/crypto_util.h -@@ -498,9 +498,10 @@ class DeriveBitsJob final : public CryptoJob { - std::move(params)) {} - - void DoThreadPoolWork() override { -+ ClearErrorOnReturn clear_error_on_return; - if (!DeriveBitsTraits::DeriveBits( - AsyncWrap::env(), -- *CryptoJob::params(), &out_)) { -+ *CryptoJob::params(), &out_, this->mode())) { - CryptoErrorStore* errors = CryptoJob::errors(); - errors->Capture(); - if (errors->Empty()) -diff --git a/test/parallel/test-crypto-async-sign-verify.js b/test/parallel/test-crypto-async-sign-verify.js -index 4e3c32fd..5924d36e 100644 ---- a/test/parallel/test-crypto-async-sign-verify.js -+++ b/test/parallel/test-crypto-async-sign-verify.js -@@ -141,3 +141,29 @@ test('dsa_public.pem', 'dsa_private.pem', 'sha256', false, - }) - .catch(common.mustNotCall()); - } -+ -+{ -+ const untrustedKey = `-----BEGIN PUBLIC KEY----- -+MCowBQYDK2VuAyEA6pwGRbadNQAI/tYN8+/p/0/hbsdHfOEGr1ADiLVk/Gc= -+-----END PUBLIC KEY-----`; -+ const data = crypto.randomBytes(32); -+ const signature = crypto.randomBytes(16); -+ -+ const expected = common.hasOpenSSL3 ? -+ /operation not supported for this keytype/ : /no default digest/; -+ -+ crypto.verify(undefined, data, untrustedKey, signature, common.mustCall((err) => { -+ assert.ok(err); -+ assert.match(err.message, expected); -+ })); -+} -+ -+{ -+ const { privateKey } = crypto.generateKeyPairSync('rsa', { -+ modulusLength: 512 -+ }); -+ crypto.sign('sha512', 'message', privateKey, common.mustCall((err) => { -+ assert.ok(err); -+ assert.match(err.message, /digest too big for rsa key/); -+ })); -+} --- -2.34.1 - diff --git a/SPECS/nodejs/CVE-2025-47279.patch b/SPECS/nodejs/CVE-2025-47279.patch deleted file mode 100644 index 32e733d8519..00000000000 --- a/SPECS/nodejs/CVE-2025-47279.patch +++ /dev/null @@ -1,39 +0,0 @@ -From 65cefbb3615e056330686cf5ffd1f7201fd8db58 Mon Sep 17 00:00:00 2001 -From: Aninda -Date: Mon, 19 May 2025 20:44:26 -0400 -Subject: [PATCH] Address CVE-2025-47279 -Upstream Patch Reference: https://github.com/nodejs/undici/commit/f317618ec28753a4218beccea048bcf89c36db25 - ---- - deps/undici/src/lib/dispatcher/pool.js | 15 +++++++++++++++ - 1 file changed, 15 insertions(+) - -diff --git a/deps/undici/src/lib/dispatcher/pool.js b/deps/undici/src/lib/dispatcher/pool.js -index 0ba3a2b5..8cea1476 100644 ---- a/deps/undici/src/lib/dispatcher/pool.js -+++ b/deps/undici/src/lib/dispatcher/pool.js -@@ -73,6 +73,21 @@ class Pool extends PoolBase { - ? { ...options.interceptors } - : undefined - this[kFactory] = factory -+ -+ this.on('connectionError', (origin, targets, error) => { -+ // If a connection error occurs, we remove the client from the pool, -+ // and emit a connectionError event. They will not be re-used. -+ // Fixes https://github.com/nodejs/undici/issues/3895 -+ for (const target of targets) { -+ // Do not use kRemoveClient here, as it will close the client, -+ // but the client cannot be closed in this state. -+ const idx = this[kClients].indexOf(target) -+ if (idx !== -1) { -+ this[kClients].splice(idx, 1) -+ } -+ } -+ }) -+ - } - - [kGetDispatcher] () { --- -2.34.1 - diff --git a/SPECS/nodejs/CVE-2025-5222.patch b/SPECS/nodejs/CVE-2025-5222.patch deleted file mode 100644 index 73e82d48541..00000000000 --- a/SPECS/nodejs/CVE-2025-5222.patch +++ /dev/null @@ -1,164 +0,0 @@ -From 87e1ef3c27772750cf717253738886a1c04b7b29 Mon Sep 17 00:00:00 2001 -From: Frank Tang -Date: Wed, 22 Jan 2025 11:50:59 -0800 -Subject: [PATCH] ICU-22973 Fix buffer overflow by using CharString - -Signed-off-by: Azure Linux Security Servicing Account -Upstream-reference: https://github.com/unicode-org/icu/commit/2c667e31cfd0b6bb1923627a932fd3453a5bac77.patch ---- - deps/icu-small/source/tools/genrb/parse.cpp | 49 ++++++++++++--------- - 1 file changed, 29 insertions(+), 20 deletions(-) - -diff --git a/deps/icu-small/source/tools/genrb/parse.cpp b/deps/icu-small/source/tools/genrb/parse.cpp -index a6c59948..799a2241 100644 ---- a/deps/icu-small/source/tools/genrb/parse.cpp -+++ b/deps/icu-small/source/tools/genrb/parse.cpp -@@ -1153,7 +1153,7 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp - struct UString *tokenValue; - struct UString comment; - enum ETokenType token; -- char subtag[1024]; -+ CharString subtag; - UnicodeString rules; - UBool haveRules = false; - UVersionInfo version; -@@ -1189,15 +1189,15 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp - return nullptr; - } - -- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); -- -+ subtag.clear(); -+ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); - if (U_FAILURE(*status)) - { - res_close(result); - return nullptr; - } - -- member = parseResource(state, subtag, nullptr, status); -+ member = parseResource(state, subtag.data(), nullptr, status); - - if (U_FAILURE(*status)) - { -@@ -1208,7 +1208,7 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp - { - // Ignore the parsed resources, continue parsing. - } -- else if (uprv_strcmp(subtag, "Version") == 0 && member->isString()) -+ else if (uprv_strcmp(subtag.data(), "Version") == 0 && member->isString()) - { - StringResource *sr = static_cast(member); - char ver[40]; -@@ -1225,11 +1225,11 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp - result->add(member, line, *status); - member = nullptr; - } -- else if(uprv_strcmp(subtag, "%%CollationBin")==0) -+ else if(uprv_strcmp(subtag.data(), "%%CollationBin")==0) - { - /* discard duplicate %%CollationBin if any*/ - } -- else if (uprv_strcmp(subtag, "Sequence") == 0 && member->isString()) -+ else if (uprv_strcmp(subtag.data(), "Sequence") == 0 && member->isString()) - { - StringResource *sr = static_cast(member); - rules = sr->fString; -@@ -1395,7 +1395,7 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n - struct UString *tokenValue; - struct UString comment; - enum ETokenType token; -- char subtag[1024], typeKeyword[1024]; -+ CharString subtag, typeKeyword; - uint32_t line; - - result = table_open(state->bundle, tag, nullptr, status); -@@ -1437,7 +1437,8 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n - return nullptr; - } - -- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); -+ subtag.clear(); -+ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); - - if (U_FAILURE(*status)) - { -@@ -1445,9 +1446,9 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n - return nullptr; - } - -- if (uprv_strcmp(subtag, "default") == 0) -+ if (uprv_strcmp(subtag.data(), "default") == 0) - { -- member = parseResource(state, subtag, nullptr, status); -+ member = parseResource(state, subtag.data(), nullptr, status); - - if (U_FAILURE(*status)) - { -@@ -1466,22 +1467,29 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n - if(token == TOK_OPEN_BRACE) { - token = getToken(state, &tokenValue, &comment, &line, status); - TableResource *collationRes; -- if (keepCollationType(subtag)) { -- collationRes = table_open(state->bundle, subtag, nullptr, status); -+ if (keepCollationType(subtag.data())) { -+ collationRes = table_open(state->bundle, subtag.data(), nullptr, status); - } else { - collationRes = nullptr; - } - // need to parse the collation data regardless -- collationRes = addCollation(state, collationRes, subtag, startline, status); -+ collationRes = addCollation(state, collationRes, subtag.data(), startline, status); - if (collationRes != nullptr) { - result->add(collationRes, startline, *status); - } - } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */ - /* we could have a table too */ - token = peekToken(state, 1, &tokenValue, &line, &comment, status); -- u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1); -- if(uprv_strcmp(typeKeyword, "alias") == 0) { -- member = parseResource(state, subtag, nullptr, status); -+ typeKeyword.clear(); -+ typeKeyword.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); -+ if (U_FAILURE(*status)) -+ { -+ res_close(result); -+ return nullptr; -+ } -+ -+ if(uprv_strcmp(typeKeyword.data(), "alias") == 0) { -+ member = parseResource(state, subtag.data(), nullptr, status); - if (U_FAILURE(*status)) - { - res_close(result); -@@ -1523,7 +1531,7 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star - struct UString *tokenValue=nullptr; - struct UString comment; - enum ETokenType token; -- char subtag[1024]; -+ CharString subtag; - uint32_t line; - UBool readToken = false; - -@@ -1562,7 +1570,8 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star - } - - if(uprv_isInvariantUString(tokenValue->fChars, -1)) { -- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); -+ subtag.clear(); -+ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); - } else { - *status = U_INVALID_FORMAT_ERROR; - error(line, "invariant characters required for table keys"); -@@ -1575,7 +1584,7 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star - return nullptr; - } - -- member = parseResource(state, subtag, &comment, status); -+ member = parseResource(state, subtag.data(), &comment, status); - - if (member == nullptr || U_FAILURE(*status)) - { --- -2.45.4 - diff --git a/SPECS/nodejs/btest402.js b/SPECS/nodejs/btest402.js new file mode 100644 index 00000000000..fd3e66d5e85 --- /dev/null +++ b/SPECS/nodejs/btest402.js @@ -0,0 +1,151 @@ +// Copyright (C) 2014 IBM Corporation and Others. All Rights Reserved. +// This file is part of the Node.JS ICU enablement work +// https://github.com/joyent/node/pull/7719 +// and is under the same license. +// +// This is a very, very, very basic test of es402 +// +// URL: https://github.com/srl295/btest402 +// Author: Steven R. Loomis +// +// for a complete test, see http://test262.ecmascript.org +// +// Usage: node btest402.js + +try { + console.log("You have console.log."); +} catch(e) { + // this works on d8 + console = { log: print }; + console.log("Now you have console.log."); +} + +function runbtest() { + var summary = {}; + + try { + var i = Intl; + summary.haveIntl = true; + console.log("+ Congrats, you have the Intl object."); + } catch(e) { + console.log("You don't have the Intl object: " + e); + } + + if(summary.haveIntl) { + var locs = [ "en", "mt", "ja","tlh"]; + var d = new Date(196400000); + for ( var n=0; n 0 ) { + lsummary.haveSlo = true; + } + } catch (e) { + console.log("SLO err: " + e); + } + var dstr = "ERR"; + try { + lsummary.dstr = d.toLocaleString(loc,{month: "long",day:"numeric",weekday:"long",year:"numeric"}); + console.log(" date: (supported:"+sl+") " + lsummary.dstr); + } catch (e) { + console.log(" Date Format err: " + e); + } + try { + new Intl.v8BreakIterator(); + console.log(" Intl.v8BreakIterator:" + + Intl.v8BreakIterator.supportedLocalesOf(loc) + " Supported, first()==" + + new Intl.v8BreakIterator(loc).first() ); + lsummary.brkOk = true; + } catch ( e) { + console.log(" Intl.v8BreakIterator error (NOT part of EcmaScript402): " + e); + } + console.log(); + } + } + + // print summary + console.log(); + console.log("--------- Analysis ---------"); + stxt = ""; + if( summary.haveIntl ) { + console.log("* You have the 'Intl' object. Congratulations! You have the possibility of being EcmaScript 402 compliant."); + stxt += "Have Intl, "; + + if ( !summary.en.haveSlo ) { + stxt += "Date:no EN, "; + console.log("* English isn't a supported language by the date formatter. Perhaps the data isn't installed properly?"); + } + if ( !summary.tlh.haveSlo ) { + stxt += "Date:no 'tlh', "; + console.log("* Klingon isn't a supported language by the date formatter. It is without honor!"); + } + // now, what is it actually saying + if( summary.en.dstr.indexOf("1970") == -1) { + stxt += "Date:bad 'en', "; + console.log("* the English date format text looks bad to me. Doesn't even have the year."); + } else { + if( summary.en.dstr.indexOf("Jan") == -1) { + stxt += "Date:bad 'en', "; + console.log("* The English date format text looks bad to me. Doesn't have the right month."); + } + } + + if( summary.mt.dstr == summary.en.dstr ) { + stxt += "Date:'mt'=='en', "; + console.log("* The English and Maltese look the same to me. Probably a 'small' build."); + } else if( summary.mt.dstr.indexOf("1970") == -1) { + stxt += "Date:bad 'mt', "; + console.log("* the Maltese date format text looks bad to me. Doesn't even have the year. (This data is missing from the Chromium ICU build)"); + } else { + if( summary.mt.dstr.indexOf("Jann") == -1) { + stxt += "Date:bad 'mt', "; + console.log("* The Maltese date format text looks bad to me. Doesn't have the right month. (This data is missing from the Chromium ICU build)"); + } + } + + if ( !summary.ja.haveSlo ) { + stxt += "Date:no 'ja', "; + console.log("* Japanese isn't a supported language by the date formatter. Could be a 'small' build."); + } else { + if( summary.ja.dstr.indexOf("1970") == -1) { + stxt += "Date:bad 'ja', "; + console.log("* the Japanese date format text looks bad to me. Doesn't even have the year."); + } else { + if( summary.ja.dstr.indexOf("日") == -1) { + stxt += "Date:bad 'ja', "; + console.log("* The Japanese date format text looks bad to me."); + } + } + } + if ( summary.en.brkOk ) { + stxt += "FYI: v8Brk:have 'en', "; + console.log("* You have Intl.v8BreakIterator support. (Note: not part of ES402.)"); + } + } else { + console.log("* You don't have the 'Intl' object. You aren't EcmaScript 402 compliant."); + stxt += " NO Intl. "; + } + + // 1-liner. + console.log(); + console.log("----------------"); + console.log( "SUMMARY:" + stxt ); +} + +var dorun = true; + +try { + if(btest402_noautorun) { + dorun = false; + } +} catch(e) {} + +if(dorun) { + console.log("Running btest.."); + runbtest(); +} diff --git a/SPECS/nodejs/nodejs.signatures.json b/SPECS/nodejs/nodejs.signatures.json index f959741983d..40e234acd2f 100644 --- a/SPECS/nodejs/nodejs.signatures.json +++ b/SPECS/nodejs/nodejs.signatures.json @@ -1,5 +1,8 @@ { "Signatures": { + "btest402.js": "cc1b9a6b3dfdb4e43716e792f74e90a4c0fa4da4863e3d28c2a8ee13179a0791", + "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", + "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", "node-v24.11.1.tar.xz": "02bdfec532370eca7ed919478cd6453bdf43b89c7350e6a303adae2958c4ee43" } } \ No newline at end of file diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index b30b308d55e..5c983a57c43 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -1,11 +1,22 @@ # Retrieved from 'deps/npm/package.json' inside the sources tarball. -%define npm_version 10.7.0 +%define npm_version 11.6.2 + +%global nodejs_datadir %{_datarootdir}/nodejs + +# ICU - from tools/icu/current_ver.dep +%global icu_major 77 +%global icu_minor 1 +%global icu_version %{icu_major}.%{icu_minor} + +%global icudatadir %{nodejs_datadir}/icudata +%{!?little_endian: %global little_endian %(%{python3} -c "import sys;print (0 if sys.byteorder=='big' else 1)")} + Summary: A JavaScript runtime built on Chrome's V8 JavaScript engine. Name: nodejs # WARNINGS: MUST check and update the 'npm_version' macro for every version update of this package. # The version of NPM can be found inside the sources under 'deps/npm/package.json'. Version: 24.11.1 -Release: 10%{?dist} +Release: 1%{?dist} License: BSD AND MIT AND Public Domain AND NAIST-2003 AND Artistic-2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -15,21 +26,15 @@ URL: https://github.com/nodejs/node # !!!! because it contains patented algorithms. # !!! => use generate_source_tarball.sh script to create a clean and reproducible source tarball. Source0: https://nodejs.org/download/release/v%{version}/node-v%{version}.tar.xz -#Patch0: disable-tlsv1-tlsv1-1.patch -#Patch1: CVE-2019-10906.patch -#Patch2: CVE-2024-21538.patch -#Patch3: CVE-2025-23083.patch -#Patch4: CVE-2025-22150.patch -#Patch5: CVE-2025-23085.patch -#Patch6: CVE-2024-22020.patch -#Patch7: CVE-2024-22195.patch -#Patch8: CVE-2020-28493.patch -#Patch9: CVE-2024-34064.patch -#Patch10: CVE-2025-27516.patch -#Patch11: CVE-2025-47279.patch -#Patch12: CVE-2025-23165.patch -#Patch13: CVE-2025-23166.patch -#Patch14: CVE-2025-5222.patch +Source1: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-b.zip +Source2: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-l.zip +Source3: btest402.js +Patch0: disable-tlsv1-tlsv1-1.patch +Patch1: CVE-2019-10906.patch +Patch2: CVE-2024-22195.patch +Patch3: CVE-2020-28493.patch +Patch4: CVE-2024-34064.patch +Patch5: CVE-2025-27516.patch BuildRequires: brotli-devel BuildRequires: c-ares-devel BuildRequires: coreutils >= 8.22 @@ -45,6 +50,9 @@ Requires: c-ares Requires: coreutils >= 8.22 Requires: openssl >= 1.1.1 +Recommends: nodejs-full-i18n = %{version}-%{release} +Provides: bundled(icu) = %{icu_version} + %description Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. @@ -62,6 +70,14 @@ Requires: zlib-devel The nodejs-devel package contains libraries, header files and documentation for developing applications that use nodejs. +%package full-i18n +Summary: Non-English locale data for Node.js +Requires: %{name} = %{version}-%{release} + +%description full-i18n +Optional data files to provide full-icu support for Node.js. Remove this +package to save space if non-English locales are not needed. + %package npm Summary: Node.js Package Manager Group: System Environment/Base @@ -98,6 +114,7 @@ python3 configure.py \ --shared-brotli \ --with-intl=small-icu \ --with-icu-source=deps/icu-small \ + --with-icu-default-data-dir=%{icudatadir} \ --openssl-use-def-ca-store \ --shared-cares @@ -115,7 +132,18 @@ for FILE in .gitmodules .gitignore .npmignore .travis.yml \*.py[co]; do find %{buildroot}%{_libdir}/node_modules/ -name "$FILE" -delete done +# Install the full-icu data files +mkdir -p %{buildroot}%{icudatadir} +%if 0%{?little_endian} +unzip -d %{buildroot}%{icudatadir} %{SOURCE2} icudt%{icu_major}l.dat +%else +unzip -d %{buildroot}%{icudatadir} %{SOURCE1} icudt%{icu_major}b.dat +%endif + %check +# Make sure i18n support is working +NODE_PATH=%{buildroot}%{_prefix}/lib/node_modules:%{buildroot}%{_prefix}/lib/node_modules/npm/node_modules LD_LIBRARY_PATH=%{buildroot}%{_libdir} %{buildroot}/%{_bindir}/node --icu-data-dir=%{buildroot}%{icudatadir} %{SOURCE3} + make cctest %post -p /sbin/ldconfig @@ -133,6 +161,10 @@ make cctest %{_includedir}/* %{_docdir}/* +%files full-i18n +%dir %{icudatadir} +%{icudatadir}/icudt%{icu_major}*.dat + %files npm %defattr(-,root,root) %{_bindir}/npm @@ -141,6 +173,10 @@ make cctest %{_prefix}/lib/node_modules/* %changelog +* Tue Dec 23 2025 Sandeep Karambelkar - 24.11.1-1 +- Upgrade to 24.11.1 +- Add support for passing runtime internationalization data + * Fri Nov 07 2025 Azure Linux Security Servicing Account - 20.14.0-10 - Patch for CVE-2025-5222 From 6509651394a11ab4a6752972bbaf8000b9e9a11a Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Wed, 24 Dec 2025 05:00:36 +0000 Subject: [PATCH 03/11] Update latest LTS version --- SPECS/nodejs/nodejs.spec | 2 +- cgmanifest.json | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index 5c983a57c43..e54eda903d3 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -15,7 +15,7 @@ Summary: A JavaScript runtime built on Chrome's V8 JavaScript engine. Name: nodejs # WARNINGS: MUST check and update the 'npm_version' macro for every version update of this package. # The version of NPM can be found inside the sources under 'deps/npm/package.json'. -Version: 24.11.1 +Version: 24.12.0 Release: 1%{?dist} License: BSD AND MIT AND Public Domain AND NAIST-2003 AND Artistic-2.0 Vendor: Microsoft Corporation diff --git a/cgmanifest.json b/cgmanifest.json index 193fc5209d8..8ee408a074b 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -14422,8 +14422,8 @@ "type": "other", "other": { "name": "nodejs", - "version": "20.14.0", - "downloadUrl": "https://nodejs.org/download/release/v20.14.0/node-v20.14.0.tar.xz" + "version": "24.12.0", + "downloadUrl": "https://nodejs.org/download/release/v24.12.0/node-v24.12.0.tar.xz" } } }, From 633e9e928e1f437468bff27f408064d24b98bf79 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Wed, 24 Dec 2025 06:46:46 +0000 Subject: [PATCH 04/11] Update nodejs 24.12 signature --- SPECS/nodejs/nodejs.signatures.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/SPECS/nodejs/nodejs.signatures.json b/SPECS/nodejs/nodejs.signatures.json index 40e234acd2f..34e4d4b99f9 100644 --- a/SPECS/nodejs/nodejs.signatures.json +++ b/SPECS/nodejs/nodejs.signatures.json @@ -3,6 +3,6 @@ "btest402.js": "cc1b9a6b3dfdb4e43716e792f74e90a4c0fa4da4863e3d28c2a8ee13179a0791", "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", - "node-v24.11.1.tar.xz": "02bdfec532370eca7ed919478cd6453bdf43b89c7350e6a303adae2958c4ee43" + "node-v24.12.0.tar.xz": "3541292851cb97d0e31b7b4943863c442f670a1af0534b3d8fa928aa1cc633b9" } } \ No newline at end of file From 9f2132461e54730187c2f4ac293757b385987475 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Wed, 24 Dec 2025 16:24:00 +0530 Subject: [PATCH 05/11] Apply suggestions from code review from copilot Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- SPECS/nodejs/btest402.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/SPECS/nodejs/btest402.js b/SPECS/nodejs/btest402.js index fd3e66d5e85..835deb31122 100644 --- a/SPECS/nodejs/btest402.js +++ b/SPECS/nodejs/btest402.js @@ -24,7 +24,6 @@ function runbtest() { var summary = {}; try { - var i = Intl; summary.haveIntl = true; console.log("+ Congrats, you have the Intl object."); } catch(e) { @@ -48,7 +47,6 @@ function runbtest() { } catch (e) { console.log("SLO err: " + e); } - var dstr = "ERR"; try { lsummary.dstr = d.toLocaleString(loc,{month: "long",day:"numeric",weekday:"long",year:"numeric"}); console.log(" date: (supported:"+sl+") " + lsummary.dstr); @@ -71,7 +69,7 @@ function runbtest() { // print summary console.log(); console.log("--------- Analysis ---------"); - stxt = ""; + var stxt = ""; if( summary.haveIntl ) { console.log("* You have the 'Intl' object. Congratulations! You have the possibility of being EcmaScript 402 compliant."); stxt += "Have Intl, "; From ffd769e76b493d0f73b65a8fa9b0a9fc5d7d7918 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Wed, 24 Dec 2025 16:26:13 +0530 Subject: [PATCH 06/11] Update SPECS/nodejs/nodejs.spec to fix version in changelog entry Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- SPECS/nodejs/nodejs.spec | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index e54eda903d3..cf37de8286b 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -173,8 +173,8 @@ make cctest %{_prefix}/lib/node_modules/* %changelog -* Tue Dec 23 2025 Sandeep Karambelkar - 24.11.1-1 -- Upgrade to 24.11.1 +* Tue Dec 23 2025 Sandeep Karambelkar - 24.12.0-1 +- Upgrade to 24.12.0 - Add support for passing runtime internationalization data * Fri Nov 07 2025 Azure Linux Security Servicing Account - 20.14.0-10 From 72e1c20075a323d5b70f4fdd9ccd82b5f62757f6 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Wed, 24 Dec 2025 16:27:11 +0530 Subject: [PATCH 07/11] Update SPECS/nodejs/nodejs.signatures.json fix json formatting Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- SPECS/nodejs/nodejs.signatures.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SPECS/nodejs/nodejs.signatures.json b/SPECS/nodejs/nodejs.signatures.json index 34e4d4b99f9..de47cd163d6 100644 --- a/SPECS/nodejs/nodejs.signatures.json +++ b/SPECS/nodejs/nodejs.signatures.json @@ -1,8 +1,8 @@ { - "Signatures": { - "btest402.js": "cc1b9a6b3dfdb4e43716e792f74e90a4c0fa4da4863e3d28c2a8ee13179a0791", - "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", - "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", - "node-v24.12.0.tar.xz": "3541292851cb97d0e31b7b4943863c442f670a1af0534b3d8fa928aa1cc633b9" - } + "Signatures": { + "btest402.js": "cc1b9a6b3dfdb4e43716e792f74e90a4c0fa4da4863e3d28c2a8ee13179a0791", + "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", + "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", + "node-v24.11.1.tar.xz": "02bdfec532370eca7ed919478cd6453bdf43b89c7350e6a303adae2958c4ee43" + } } \ No newline at end of file From fbd9da145ad5c507687ac2f8b208a4e0bbddba88 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Wed, 24 Dec 2025 09:37:29 +0000 Subject: [PATCH 08/11] Fix file signatures --- SPECS/nodejs/nodejs.signatures.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/SPECS/nodejs/nodejs.signatures.json b/SPECS/nodejs/nodejs.signatures.json index de47cd163d6..5078533f52d 100644 --- a/SPECS/nodejs/nodejs.signatures.json +++ b/SPECS/nodejs/nodejs.signatures.json @@ -1,8 +1,8 @@ { - "Signatures": { - "btest402.js": "cc1b9a6b3dfdb4e43716e792f74e90a4c0fa4da4863e3d28c2a8ee13179a0791", - "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", - "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", - "node-v24.11.1.tar.xz": "02bdfec532370eca7ed919478cd6453bdf43b89c7350e6a303adae2958c4ee43" - } + "Signatures": { + "btest402.js": "fabaf4dacc13e93d54f825b87ffde18573214b149388a5f96176236dd31d7768", + "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", + "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", + "node-v24.12.0.tar.xz": "3541292851cb97d0e31b7b4943863c442f670a1af0534b3d8fa928aa1cc633b9" + } } \ No newline at end of file From 7267ae518fbf5d5c8cdc860f2cd27edc27516812 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Thu, 8 Jan 2026 06:49:51 +0000 Subject: [PATCH 09/11] add nodejs and nodejs24 together co existing in azurelinux --- SPECS/nodejs/CVE-2024-21538.patch | 36 ++ SPECS/nodejs/CVE-2024-22020.patch | 46 ++ SPECS/nodejs/CVE-2025-22150.patch | 40 ++ SPECS/nodejs/CVE-2025-23083.patch | 94 ++++ SPECS/nodejs/CVE-2025-23085.patch | 200 ++++++++ SPECS/nodejs/CVE-2025-23165.patch | 28 ++ SPECS/nodejs/CVE-2025-23166.patch | 537 +++++++++++++++++++++ SPECS/nodejs/CVE-2025-47279.patch | 39 ++ SPECS/nodejs/CVE-2025-5222.patch | 164 +++++++ SPECS/nodejs/nodejs.signatures.json | 11 +- SPECS/nodejs/nodejs.spec | 68 +-- SPECS/nodejs24/CVE-2019-10906.patch | 197 ++++++++ SPECS/nodejs24/CVE-2020-28493.patch | 134 +++++ SPECS/nodejs24/CVE-2024-22195.patch | 64 +++ SPECS/nodejs24/CVE-2024-34064.patch | 68 +++ SPECS/nodejs24/CVE-2025-27516.patch | 68 +++ SPECS/{nodejs => nodejs24}/btest402.js | 0 SPECS/nodejs24/disable-tlsv1-tlsv1-1.patch | 42 ++ SPECS/nodejs24/generate_source_tarball.sh | 117 +++++ SPECS/nodejs24/nodejs24.signatures.json | 8 + SPECS/nodejs24/nodejs24.spec | 327 +++++++++++++ cgmanifest.json | 10 + 22 files changed, 2239 insertions(+), 59 deletions(-) create mode 100644 SPECS/nodejs/CVE-2024-21538.patch create mode 100644 SPECS/nodejs/CVE-2024-22020.patch create mode 100644 SPECS/nodejs/CVE-2025-22150.patch create mode 100644 SPECS/nodejs/CVE-2025-23083.patch create mode 100644 SPECS/nodejs/CVE-2025-23085.patch create mode 100644 SPECS/nodejs/CVE-2025-23165.patch create mode 100644 SPECS/nodejs/CVE-2025-23166.patch create mode 100644 SPECS/nodejs/CVE-2025-47279.patch create mode 100644 SPECS/nodejs/CVE-2025-5222.patch create mode 100644 SPECS/nodejs24/CVE-2019-10906.patch create mode 100644 SPECS/nodejs24/CVE-2020-28493.patch create mode 100644 SPECS/nodejs24/CVE-2024-22195.patch create mode 100644 SPECS/nodejs24/CVE-2024-34064.patch create mode 100644 SPECS/nodejs24/CVE-2025-27516.patch rename SPECS/{nodejs => nodejs24}/btest402.js (100%) create mode 100644 SPECS/nodejs24/disable-tlsv1-tlsv1-1.patch create mode 100755 SPECS/nodejs24/generate_source_tarball.sh create mode 100644 SPECS/nodejs24/nodejs24.signatures.json create mode 100644 SPECS/nodejs24/nodejs24.spec diff --git a/SPECS/nodejs/CVE-2024-21538.patch b/SPECS/nodejs/CVE-2024-21538.patch new file mode 100644 index 00000000000..7620a62ff46 --- /dev/null +++ b/SPECS/nodejs/CVE-2024-21538.patch @@ -0,0 +1,36 @@ +From ea1368b332cebba727436bf4dddebb0c5d7a9d5b Mon Sep 17 00:00:00 2001 +From: bala +Date: Tue, 19 Nov 2024 12:03:43 +0000 +Subject: [PATCH] Vendor patch applied to fix CVE-2024-21538 + +--- + deps/npm/node_modules/cross-spawn/lib/util/escape.js | 6 ++++-- + 1 file changed, 4 insertions(+), 2 deletions(-) + +diff --git a/deps/npm/node_modules/cross-spawn/lib/util/escape.js b/deps/npm/node_modules/cross-spawn/lib/util/escape.js +index b0bb84c..e4804b9 100644 +--- a/deps/npm/node_modules/cross-spawn/lib/util/escape.js ++++ b/deps/npm/node_modules/cross-spawn/lib/util/escape.js +@@ -15,15 +15,17 @@ function escapeArgument(arg, doubleEscapeMetaChars) { + arg = `${arg}`; + + // Algorithm below is based on https://qntm.org/cmd ++ // It's slightly altered to disable JS backtracking to avoid hanging on specially crafted input ++ // Please see https://github.com/moxystudio/node-cross-spawn/pull/160 for more information + + // Sequence of backslashes followed by a double quote: + // double up all the backslashes and escape the double quote +- arg = arg.replace(/(\\*)"/g, '$1$1\\"'); ++ arg = arg.replace(/(?=\\*?)"/g, '$1$1\\"'); + + // Sequence of backslashes followed by the end of the string + // (which will become a double quote later): + // double up all the backslashes +- arg = arg.replace(/(\\*)$/, '$1$1'); ++ arg = arg.replace(/(?=\\*?)$/, '$1$1'); + + // All other backslashes occur literally + +-- +2.39.4 + diff --git a/SPECS/nodejs/CVE-2024-22020.patch b/SPECS/nodejs/CVE-2024-22020.patch new file mode 100644 index 00000000000..563ea2a6f4a --- /dev/null +++ b/SPECS/nodejs/CVE-2024-22020.patch @@ -0,0 +1,46 @@ +From 9defa3bb7532c1b7f3ea51aed9989954382ea5a9 Mon Sep 17 00:00:00 2001 +From: Kanishk-Bansal +Date: Tue, 11 Feb 2025 17:25:37 +0000 +Subject: [PATCH] Fix CVE-2024-22020 + +--- + lib/internal/modules/esm/resolve.js | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +diff --git a/lib/internal/modules/esm/resolve.js b/lib/internal/modules/esm/resolve.js +index b56ad6cc..8cd08de8 100644 +--- a/lib/internal/modules/esm/resolve.js ++++ b/lib/internal/modules/esm/resolve.js +@@ -1108,6 +1108,17 @@ function defaultResolve(specifier, context = {}) { + + // Avoid accessing the `protocol` property due to the lazy getters. + protocol = parsed.protocol; ++ ++ if (protocol === 'data:' && ++ parsedParentURL.protocol !== 'file:' && ++ experimentalNetworkImports) { ++ throw new ERR_NETWORK_IMPORT_DISALLOWED( ++ specifier, ++ parsedParentURL, ++ 'import data: from a non file: is not allowed', ++ ); ++ } ++ + if (protocol === 'data:' || + (experimentalNetworkImports && + ( +@@ -1118,7 +1129,10 @@ function defaultResolve(specifier, context = {}) { + ) { + return { __proto__: null, url: parsed.href }; + } +- } catch { ++ } catch (e) { ++ if (e?.code === 'ERR_NETWORK_IMPORT_DISALLOWED') { ++ throw e; ++ } + // Ignore exception + } + +-- +2.45.2 + diff --git a/SPECS/nodejs/CVE-2025-22150.patch b/SPECS/nodejs/CVE-2025-22150.patch new file mode 100644 index 00000000000..9634c621992 --- /dev/null +++ b/SPECS/nodejs/CVE-2025-22150.patch @@ -0,0 +1,40 @@ +From 7a5aff9d9e6b6b541f7528cedb9bcf2046289f1a Mon Sep 17 00:00:00 2001 +From: Kanishk Bansal +Date: Wed, 5 Feb 2025 12:14:46 +0000 +Subject: [PATCH] Address CVE-2025-22150 + +--- + deps/undici/src/lib/web/fetch/body.js | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/deps/undici/src/lib/web/fetch/body.js b/deps/undici/src/lib/web/fetch/body.js +index 26cce5f3..594620b5 100644 +--- a/deps/undici/src/lib/web/fetch/body.js ++++ b/deps/undici/src/lib/web/fetch/body.js +@@ -20,6 +20,14 @@ const { isErrored } = require('../../core/util') + const { isArrayBuffer } = require('node:util/types') + const { serializeAMimeType } = require('./data-url') + const { multipartFormDataParser } = require('./formdata-parser') ++let random ++ ++try { ++ const crypto = require('node:crypto') ++ random = (max) => crypto.randomInt(0, max) ++} catch { ++ random = (max) => Math.floor(Math.random(max)) ++} + + const textEncoder = new TextEncoder() + +@@ -100,7 +108,7 @@ function extractBody (object, keepalive = false) { + // Set source to a copy of the bytes held by object. + source = new Uint8Array(object.buffer.slice(object.byteOffset, object.byteOffset + object.byteLength)) + } else if (util.isFormDataLike(object)) { +- const boundary = `----formdata-undici-0${`${Math.floor(Math.random() * 1e11)}`.padStart(11, '0')}` ++ const boundary = `----formdata-undici-0${`${random(1e11)}`.padStart(11, '0')}` + const prefix = `--${boundary}\r\nContent-Disposition: form-data` + + /*! formdata-polyfill. MIT License. Jimmy Wärting */ +-- +2.43.0 + diff --git a/SPECS/nodejs/CVE-2025-23083.patch b/SPECS/nodejs/CVE-2025-23083.patch new file mode 100644 index 00000000000..36adf8dabd4 --- /dev/null +++ b/SPECS/nodejs/CVE-2025-23083.patch @@ -0,0 +1,94 @@ +From 389f239a282de04651cebdc99bc0af5d19aa955d Mon Sep 17 00:00:00 2001 +From: RafaelGSS +Date: Tue, 27 Aug 2024 18:00:12 -0300 +Subject: [PATCH] src,loader,permission: throw on InternalWorker use + +Previously this PR it was expected that InternalWorker +usage doesn't require the --allow-worker when the permission +model is enabled. This, however, exposes a vulnerability +whenever the instance gets accessed by the user. For example +through diagnostics_channel.subscribe('worker_threads') + +PR-URL: https://github.com/nodejs-private/node-private/pull/652 +Refs: https://hackerone.com/reports/2575105 +CVE-ID: CVE-2025-23083 +--- + src/node_worker.cc | 6 ++---- + test/es-module/test-esm-loader-hooks.mjs | 8 ++++---- + .../test-permission-dc-worker-threads.js | 19 +++++++++++++++++++ + 3 files changed, 25 insertions(+), 8 deletions(-) + create mode 100644 test/parallel/test-permission-dc-worker-threads.js + +diff --git a/src/node_worker.cc b/src/node_worker.cc +index 196eb3bc..31268115 100644 +--- a/src/node_worker.cc ++++ b/src/node_worker.cc +@@ -484,12 +484,10 @@ Worker::~Worker() { + + void Worker::New(const FunctionCallbackInfo& args) { + Environment* env = Environment::GetCurrent(args); ++ THROW_IF_INSUFFICIENT_PERMISSIONS( ++ env, permission::PermissionScope::kWorkerThreads, ""); + auto is_internal = args[5]; + CHECK(is_internal->IsBoolean()); +- if (is_internal->IsFalse()) { +- THROW_IF_INSUFFICIENT_PERMISSIONS( +- env, permission::PermissionScope::kWorkerThreads, ""); +- } + Isolate* isolate = args.GetIsolate(); + + CHECK(args.IsConstructCall()); +diff --git a/test/es-module/test-esm-loader-hooks.mjs b/test/es-module/test-esm-loader-hooks.mjs +index 8e616c0d..225ab26a 100644 +--- a/test/es-module/test-esm-loader-hooks.mjs ++++ b/test/es-module/test-esm-loader-hooks.mjs +@@ -154,7 +154,7 @@ describe('Loader hooks', { concurrency: true }, () => { + }); + }); + +- it('should work without worker permission', async () => { ++ it('should not work without worker permission', async () => { + const { code, signal, stdout, stderr } = await spawnPromisified(execPath, [ + '--no-warnings', + '--experimental-permission', +@@ -165,9 +165,9 @@ describe('Loader hooks', { concurrency: true }, () => { + fixtures.path('es-modules/esm-top-level-await.mjs'), + ]); + +- assert.strictEqual(stderr, ''); +- assert.match(stdout, /^1\r?\n2\r?\n$/); +- assert.strictEqual(code, 0); ++ assert.match(stderr, /Error: Access to this API has been restricted/); ++ assert.strictEqual(stdout, ''); ++ assert.strictEqual(code, 1); + assert.strictEqual(signal, null); + }); + +diff --git a/test/parallel/test-permission-dc-worker-threads.js b/test/parallel/test-permission-dc-worker-threads.js +new file mode 100644 +index 00000000..73cbf029 +--- /dev/null ++++ b/test/parallel/test-permission-dc-worker-threads.js +@@ -0,0 +1,19 @@ ++// Flags: --experimental-permission --allow-fs-read=* --experimental-test-module-mocks ++'use strict'; ++ ++const common = require('../common'); ++const assert = require('node:assert'); ++ ++{ ++ const diagnostics_channel = require('node:diagnostics_channel'); ++ diagnostics_channel.subscribe('worker_threads', common.mustNotCall()); ++ const { mock } = require('node:test'); ++ ++ // Module mocking should throw instead of posting to worker_threads dc ++ assert.throws(() => { ++ mock.module('node:path'); ++ }, common.expectsError({ ++ code: 'ERR_ACCESS_DENIED', ++ permission: 'WorkerThreads', ++ })); ++} +-- +2.25.1 + diff --git a/SPECS/nodejs/CVE-2025-23085.patch b/SPECS/nodejs/CVE-2025-23085.patch new file mode 100644 index 00000000000..e87cd44440a --- /dev/null +++ b/SPECS/nodejs/CVE-2025-23085.patch @@ -0,0 +1,200 @@ +From ea5045019e58f1d5780df3fff484d2010fd38c9d Mon Sep 17 00:00:00 2001 +From: Kanishk-Bansal +Date: Tue, 11 Feb 2025 16:05:07 +0000 +Subject: [PATCH] fix CVE-2025-23085 for 3.0 + +--- + lib/internal/http2/core.js | 15 ++++++-- + src/node_http2.cc | 36 ++++++++++++++++--- + ...2-connect-method-extended-cant-turn-off.js | 6 ++++ + ...-http2-options-max-headers-block-length.js | 4 ++- + ...tp2-options-max-headers-exceeds-nghttp2.js | 4 ++- + 5 files changed, 55 insertions(+), 10 deletions(-) + +diff --git a/lib/internal/http2/core.js b/lib/internal/http2/core.js +index 761e8713..0324432f 100644 +--- a/lib/internal/http2/core.js ++++ b/lib/internal/http2/core.js +@@ -617,11 +617,20 @@ function onFrameError(id, type, code) { + return; + debugSessionObj(session, 'error sending frame type %d on stream %d, code: %d', + type, id, code); +- const emitter = session[kState].streams.get(id) || session; ++ ++ const stream = session[kState].streams.get(id); ++ const emitter = stream || session; + emitter[kUpdateTimer](); + emitter.emit('frameError', type, code, id); +- session[kState].streams.get(id).close(code); +- session.close(); ++ ++ // When a frameError happens is not uncommon that a pending GOAWAY ++ // package from nghttp2 is on flight with a correct error code. ++ // We schedule it using setImmediate to give some time for that ++ // package to arrive. ++ setImmediate(() => { ++ stream?.close(code); ++ session.close(); ++ }); + } + + function onAltSvc(stream, origin, alt) { +diff --git a/src/node_http2.cc b/src/node_http2.cc +index eada4081..28dfe532 100644 +--- a/src/node_http2.cc ++++ b/src/node_http2.cc +@@ -844,6 +844,7 @@ bool Http2Session::CanAddStream() { + } + + void Http2Session::AddStream(Http2Stream* stream) { ++ Debug(this, "Adding stream: %d", stream->id()); + CHECK_GE(++statistics_.stream_count, 0); + streams_[stream->id()] = BaseObjectPtr(stream); + size_t size = streams_.size(); +@@ -854,6 +855,7 @@ void Http2Session::AddStream(Http2Stream* stream) { + + + BaseObjectPtr Http2Session::RemoveStream(int32_t id) { ++ Debug(this, "Removing stream: %d", id); + BaseObjectPtr stream; + if (streams_.empty()) + return stream; +@@ -1030,6 +1032,7 @@ int Http2Session::OnHeaderCallback(nghttp2_session* handle, + if (UNLIKELY(!stream)) + return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE; + ++ Debug(session, "handling header key/pair for stream %d", id); + // If the stream has already been destroyed, ignore. + if (!stream->is_destroyed() && !stream->AddHeader(name, value, flags)) { + // This will only happen if the connected peer sends us more +@@ -1099,9 +1102,21 @@ int Http2Session::OnInvalidFrame(nghttp2_session* handle, + return 1; + } + +- // If the error is fatal or if error code is ERR_STREAM_CLOSED... emit error ++ // If the error is fatal or if error code is one of the following ++ // we emit and error: ++ // ++ // ERR_STREAM_CLOSED: An invalid frame has been received in a closed stream. ++ // ++ // ERR_PROTO: The RFC 7540 specifies: ++ // "An endpoint that encounters a connection error SHOULD first send a GOAWAY ++ // frame (Section 6.8) with the stream identifier of the last stream that it ++ // successfully received from its peer. ++ // The GOAWAY frame includes an error code that indicates the type of error" ++ // The GOAWAY frame is already sent by nghttp2. We emit the error ++ // to liberate the Http2Session to destroy. + if (nghttp2_is_fatal(lib_error_code) || +- lib_error_code == NGHTTP2_ERR_STREAM_CLOSED) { ++ lib_error_code == NGHTTP2_ERR_STREAM_CLOSED || ++ lib_error_code == NGHTTP2_ERR_PROTO) { + Environment* env = session->env(); + Isolate* isolate = env->isolate(); + HandleScope scope(isolate); +@@ -1164,7 +1179,6 @@ int Http2Session::OnFrameNotSent(nghttp2_session* handle, + Debug(session, "frame type %d was not sent, code: %d", + frame->hd.type, error_code); + +- // Do not report if the frame was not sent due to the session closing + if (error_code == NGHTTP2_ERR_SESSION_CLOSING || + error_code == NGHTTP2_ERR_STREAM_CLOSED || + error_code == NGHTTP2_ERR_STREAM_CLOSING) { +@@ -1173,7 +1187,15 @@ int Http2Session::OnFrameNotSent(nghttp2_session* handle, + // to destroy the session completely. + // Further information see: https://github.com/nodejs/node/issues/35233 + session->DecrefHeaders(frame); +- return 0; ++ // Currently, nghttp2 doesn't not inform us when is the best ++ // time to call session.close(). It relies on a closing connection ++ // from peer. If that doesn't happen, the nghttp2_session will be ++ // closed but the Http2Session will still be up causing a memory leak. ++ // Therefore, if the GOAWAY frame couldn't be send due to ++ // ERR_SESSION_CLOSING we should force close from our side. ++ if (frame->hd.type != 0x03) { ++ return 0; ++ } + } + + Isolate* isolate = env->isolate(); +@@ -1239,12 +1261,15 @@ int Http2Session::OnStreamClose(nghttp2_session* handle, + // ignore these. If this callback was not provided, nghttp2 would handle + // invalid headers strictly and would shut down the stream. We are intentionally + // being more lenient here although we may want to revisit this choice later. +-int Http2Session::OnInvalidHeader(nghttp2_session* session, ++int Http2Session::OnInvalidHeader(nghttp2_session* handle, + const nghttp2_frame* frame, + nghttp2_rcbuf* name, + nghttp2_rcbuf* value, + uint8_t flags, + void* user_data) { ++ Http2Session* session = static_cast(user_data); ++ int32_t id = GetFrameID(frame); ++ Debug(session, "invalid header received for stream %d", id); + // Ignore invalid header fields by default. + return 0; + } +@@ -1638,6 +1663,7 @@ void Http2Session::HandlePingFrame(const nghttp2_frame* frame) { + + // Called by OnFrameReceived when a complete SETTINGS frame has been received. + void Http2Session::HandleSettingsFrame(const nghttp2_frame* frame) { ++ Debug(this, "handling settings frame"); + bool ack = frame->hd.flags & NGHTTP2_FLAG_ACK; + if (!ack) { + js_fields_->bitfield &= ~(1 << kSessionRemoteSettingsIsUpToDate); +diff --git a/test/parallel/test-http2-connect-method-extended-cant-turn-off.js b/test/parallel/test-http2-connect-method-extended-cant-turn-off.js +index f4d033ef..456aa1ce 100644 +--- a/test/parallel/test-http2-connect-method-extended-cant-turn-off.js ++++ b/test/parallel/test-http2-connect-method-extended-cant-turn-off.js +@@ -27,4 +27,10 @@ server.listen(0, common.mustCall(() => { + server.close(); + })); + })); ++ ++ client.on('error', common.expectsError({ ++ code: 'ERR_HTTP2_ERROR', ++ name: 'Error', ++ message: 'Protocol error' ++ })); + })); +diff --git a/test/parallel/test-http2-options-max-headers-block-length.js b/test/parallel/test-http2-options-max-headers-block-length.js +index af1cc6f9..15b142ac 100644 +--- a/test/parallel/test-http2-options-max-headers-block-length.js ++++ b/test/parallel/test-http2-options-max-headers-block-length.js +@@ -35,9 +35,11 @@ server.listen(0, common.mustCall(() => { + assert.strictEqual(code, h2.constants.NGHTTP2_FRAME_SIZE_ERROR); + })); + ++ // NGHTTP2 will automatically send the NGHTTP2_REFUSED_STREAM with ++ // the GOAWAY frame. + req.on('error', common.expectsError({ + code: 'ERR_HTTP2_STREAM_ERROR', + name: 'Error', +- message: 'Stream closed with error code NGHTTP2_FRAME_SIZE_ERROR' ++ message: 'Stream closed with error code NGHTTP2_REFUSED_STREAM' + })); + })); +diff --git a/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js b/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js +index df3aefff..7767dbbc 100644 +--- a/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js ++++ b/test/parallel/test-http2-options-max-headers-exceeds-nghttp2.js +@@ -59,6 +59,9 @@ server.listen(0, common.mustCall(() => { + 'session', + common.mustCall((session) => { + assert.strictEqual(session instanceof ServerHttp2Session, true); ++ session.on('close', common.mustCall(() => { ++ server.close(); ++ })); + }), + ); + server.on( +@@ -80,7 +83,6 @@ server.listen(0, common.mustCall(() => { + assert.strictEqual(err.name, 'Error'); + assert.strictEqual(err.message, 'Session closed with error code 9'); + assert.strictEqual(session instanceof ServerHttp2Session, true); +- server.close(); + }), + ); + +-- +2.45.2 + diff --git a/SPECS/nodejs/CVE-2025-23165.patch b/SPECS/nodejs/CVE-2025-23165.patch new file mode 100644 index 00000000000..da41f64457f --- /dev/null +++ b/SPECS/nodejs/CVE-2025-23165.patch @@ -0,0 +1,28 @@ +From 3badbd012233828132ec938253ed40a7854fd65c Mon Sep 17 00:00:00 2001 +From: Aninda +Date: Sat, 24 May 2025 11:03:53 -0400 +Subject: [PATCH] Address CVE-2025-23165 +Upstream Patch Reference: https://github.com/nodejs/node/commit/9e13bf0a81e15c7b3a9f1826dccbcea991d7e63a + +--- + src/node_file.cc | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/node_file.cc b/src/node_file.cc +index 0ec5c6f4..ba69879b 100644 +--- a/src/node_file.cc ++++ b/src/node_file.cc +@@ -2609,9 +2609,9 @@ static void ReadFileUtf8(const FunctionCallbackInfo& args) { + FS_SYNC_TRACE_END(open); + if (req.result < 0) { + uv_fs_req_cleanup(&req); +- // req will be cleaned up by scope leave. + return env->ThrowUVException(req.result, "open", nullptr, path.out()); + } ++ uv_fs_req_cleanup(&req); + } + + auto defer_close = OnScopeLeave([file, is_fd, &req]() { +-- +2.34.1 + diff --git a/SPECS/nodejs/CVE-2025-23166.patch b/SPECS/nodejs/CVE-2025-23166.patch new file mode 100644 index 00000000000..467bda09154 --- /dev/null +++ b/SPECS/nodejs/CVE-2025-23166.patch @@ -0,0 +1,537 @@ +From cca703fb8440504e580a92256a8f16ca0e38a08e Mon Sep 17 00:00:00 2001 +From: Aninda +Date: Sat, 24 May 2025 10:33:47 -0400 +Subject: [PATCH] Address CVE-2025-23166 +Upstream Patch Reference: https://github.com/nodejs/node/commit/6c57465920cf1b981a63031e71b1e4a73bf9beaa + +--- + src/crypto/crypto_dh.cc | 8 +++--- + src/crypto/crypto_dh.h | 8 +++--- + src/crypto/crypto_ec.cc | 3 +- + src/crypto/crypto_ec.h | 8 +++--- + src/crypto/crypto_hash.cc | 8 +++--- + src/crypto/crypto_hash.h | 8 +++--- + src/crypto/crypto_hkdf.cc | 8 +++--- + src/crypto/crypto_hkdf.h | 8 +++--- + src/crypto/crypto_hmac.cc | 8 +++--- + src/crypto/crypto_hmac.h | 8 +++--- + src/crypto/crypto_pbkdf2.cc | 8 +++--- + src/crypto/crypto_pbkdf2.h | 8 +++--- + src/crypto/crypto_random.cc | 20 ++++++------- + src/crypto/crypto_random.h | 19 +++++++------ + src/crypto/crypto_scrypt.cc | 8 +++--- + src/crypto/crypto_scrypt.h | 8 +++--- + src/crypto/crypto_sig.cc | 28 +++++++++++-------- + src/crypto/crypto_sig.h | 8 +++--- + src/crypto/crypto_util.h | 3 +- + .../parallel/test-crypto-async-sign-verify.js | 26 +++++++++++++++++ + 20 files changed, 122 insertions(+), 89 deletions(-) + +diff --git a/src/crypto/crypto_dh.cc b/src/crypto/crypto_dh.cc +index b4447102..7c984652 100644 +--- a/src/crypto/crypto_dh.cc ++++ b/src/crypto/crypto_dh.cc +@@ -705,10 +705,10 @@ Maybe DHBitsTraits::EncodeOutput( + return Just(!result->IsEmpty()); + } + +-bool DHBitsTraits::DeriveBits( +- Environment* env, +- const DHBitsConfig& params, +- ByteSource* out) { ++bool DHBitsTraits::DeriveBits(Environment* env, ++ const DHBitsConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + *out = StatelessDiffieHellmanThreadsafe( + params.private_key->GetAsymmetricKey(), + params.public_key->GetAsymmetricKey()); +diff --git a/src/crypto/crypto_dh.h b/src/crypto/crypto_dh.h +index ec12548d..f7c4b675 100644 +--- a/src/crypto/crypto_dh.h ++++ b/src/crypto/crypto_dh.h +@@ -131,10 +131,10 @@ struct DHBitsTraits final { + unsigned int offset, + DHBitsConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const DHBitsConfig& params, +- ByteSource* out_); ++ static bool DeriveBits(Environment* env, ++ const DHBitsConfig& params, ++ ByteSource* out_, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_ec.cc b/src/crypto/crypto_ec.cc +index 860d5048..356e21f1 100644 +--- a/src/crypto/crypto_ec.cc ++++ b/src/crypto/crypto_ec.cc +@@ -481,7 +481,8 @@ Maybe ECDHBitsTraits::AdditionalConfig( + + bool ECDHBitsTraits::DeriveBits(Environment* env, + const ECDHBitsConfig& params, +- ByteSource* out) { ++ ByteSource* out, ++ CryptoJobMode mode) { + size_t len = 0; + ManagedEVPPKey m_privkey = params.private_->GetAsymmetricKey(); + ManagedEVPPKey m_pubkey = params.public_->GetAsymmetricKey(); +diff --git a/src/crypto/crypto_ec.h b/src/crypto/crypto_ec.h +index f9570bd4..a6bd48d4 100644 +--- a/src/crypto/crypto_ec.h ++++ b/src/crypto/crypto_ec.h +@@ -77,10 +77,10 @@ struct ECDHBitsTraits final { + unsigned int offset, + ECDHBitsConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const ECDHBitsConfig& params, +- ByteSource* out_); ++ static bool DeriveBits(Environment* env, ++ const ECDHBitsConfig& params, ++ ByteSource* out_, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_hash.cc b/src/crypto/crypto_hash.cc +index 46086018..7d974d3d 100644 +--- a/src/crypto/crypto_hash.cc ++++ b/src/crypto/crypto_hash.cc +@@ -501,10 +501,10 @@ Maybe HashTraits::AdditionalConfig( + return Just(true); + } + +-bool HashTraits::DeriveBits( +- Environment* env, +- const HashConfig& params, +- ByteSource* out) { ++bool HashTraits::DeriveBits(Environment* env, ++ const HashConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + EVPMDCtxPointer ctx(EVP_MD_CTX_new()); + + if (UNLIKELY(!ctx || +diff --git a/src/crypto/crypto_hash.h b/src/crypto/crypto_hash.h +index 07e3a2ae..0ea2114f 100644 +--- a/src/crypto/crypto_hash.h ++++ b/src/crypto/crypto_hash.h +@@ -70,10 +70,10 @@ struct HashTraits final { + unsigned int offset, + HashConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const HashConfig& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const HashConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_hkdf.cc b/src/crypto/crypto_hkdf.cc +index 0dd9b424..526be1d0 100644 +--- a/src/crypto/crypto_hkdf.cc ++++ b/src/crypto/crypto_hkdf.cc +@@ -100,10 +100,10 @@ Maybe HKDFTraits::AdditionalConfig( + return Just(true); + } + +-bool HKDFTraits::DeriveBits( +- Environment* env, +- const HKDFConfig& params, +- ByteSource* out) { ++bool HKDFTraits::DeriveBits(Environment* env, ++ const HKDFConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + EVPKeyCtxPointer ctx = + EVPKeyCtxPointer(EVP_PKEY_CTX_new_id(EVP_PKEY_HKDF, nullptr)); + if (!ctx || !EVP_PKEY_derive_init(ctx.get()) || +diff --git a/src/crypto/crypto_hkdf.h b/src/crypto/crypto_hkdf.h +index c4a537ce..acd2b670 100644 +--- a/src/crypto/crypto_hkdf.h ++++ b/src/crypto/crypto_hkdf.h +@@ -42,10 +42,10 @@ struct HKDFTraits final { + unsigned int offset, + HKDFConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const HKDFConfig& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const HKDFConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_hmac.cc b/src/crypto/crypto_hmac.cc +index b101d5c7..5d81a60a 100644 +--- a/src/crypto/crypto_hmac.cc ++++ b/src/crypto/crypto_hmac.cc +@@ -220,10 +220,10 @@ Maybe HmacTraits::AdditionalConfig( + return Just(true); + } + +-bool HmacTraits::DeriveBits( +- Environment* env, +- const HmacConfig& params, +- ByteSource* out) { ++bool HmacTraits::DeriveBits(Environment* env, ++ const HmacConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + HMACCtxPointer ctx(HMAC_CTX_new()); + + if (!ctx || +diff --git a/src/crypto/crypto_hmac.h b/src/crypto/crypto_hmac.h +index c80cc36f..dd490f05 100644 +--- a/src/crypto/crypto_hmac.h ++++ b/src/crypto/crypto_hmac.h +@@ -73,10 +73,10 @@ struct HmacTraits final { + unsigned int offset, + HmacConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const HmacConfig& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const HmacConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_pbkdf2.cc b/src/crypto/crypto_pbkdf2.cc +index 963d0db6..f6d37dad 100644 +--- a/src/crypto/crypto_pbkdf2.cc ++++ b/src/crypto/crypto_pbkdf2.cc +@@ -111,10 +111,10 @@ Maybe PBKDF2Traits::AdditionalConfig( + return Just(true); + } + +-bool PBKDF2Traits::DeriveBits( +- Environment* env, +- const PBKDF2Config& params, +- ByteSource* out) { ++bool PBKDF2Traits::DeriveBits(Environment* env, ++ const PBKDF2Config& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + ByteSource::Builder buf(params.length); + + // Both pass and salt may be zero length here. +diff --git a/src/crypto/crypto_pbkdf2.h b/src/crypto/crypto_pbkdf2.h +index 6fda7cd3..11ffad78 100644 +--- a/src/crypto/crypto_pbkdf2.h ++++ b/src/crypto/crypto_pbkdf2.h +@@ -55,10 +55,10 @@ struct PBKDF2Traits final { + unsigned int offset, + PBKDF2Config* params); + +- static bool DeriveBits( +- Environment* env, +- const PBKDF2Config& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const PBKDF2Config& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc +index 48154df7..03bdcd5c 100644 +--- a/src/crypto/crypto_random.cc ++++ b/src/crypto/crypto_random.cc +@@ -56,10 +56,10 @@ Maybe RandomBytesTraits::AdditionalConfig( + return Just(true); + } + +-bool RandomBytesTraits::DeriveBits( +- Environment* env, +- const RandomBytesConfig& params, +- ByteSource* unused) { ++bool RandomBytesTraits::DeriveBits(Environment* env, ++ const RandomBytesConfig& params, ++ ByteSource* unused, ++ CryptoJobMode mode) { + return CSPRNG(params.buffer, params.size).is_ok(); + } + +@@ -151,7 +151,8 @@ Maybe RandomPrimeTraits::AdditionalConfig( + + bool RandomPrimeTraits::DeriveBits(Environment* env, + const RandomPrimeConfig& params, +- ByteSource* unused) { ++ ByteSource* unused, ++ CryptoJobMode mode) { + // BN_generate_prime_ex() calls RAND_bytes_ex() internally. + // Make sure the CSPRNG is properly seeded. + CHECK(CSPRNG(nullptr, 0).is_ok()); +@@ -194,11 +195,10 @@ Maybe CheckPrimeTraits::AdditionalConfig( + return Just(true); + } + +-bool CheckPrimeTraits::DeriveBits( +- Environment* env, +- const CheckPrimeConfig& params, +- ByteSource* out) { +- ++bool CheckPrimeTraits::DeriveBits(Environment* env, ++ const CheckPrimeConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + BignumCtxPointer ctx(BN_CTX_new()); + + int ret = BN_is_prime_ex( +diff --git a/src/crypto/crypto_random.h b/src/crypto/crypto_random.h +index a2807ed6..b673cbbf 100644 +--- a/src/crypto/crypto_random.h ++++ b/src/crypto/crypto_random.h +@@ -32,10 +32,10 @@ struct RandomBytesTraits final { + unsigned int offset, + RandomBytesConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const RandomBytesConfig& params, +- ByteSource* out_); ++ static bool DeriveBits(Environment* env, ++ const RandomBytesConfig& params, ++ ByteSource* out_, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +@@ -72,7 +72,8 @@ struct RandomPrimeTraits final { + static bool DeriveBits( + Environment* env, + const RandomPrimeConfig& params, +- ByteSource* out_); ++ ByteSource* out_, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +@@ -105,10 +106,10 @@ struct CheckPrimeTraits final { + unsigned int offset, + CheckPrimeConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const CheckPrimeConfig& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const CheckPrimeConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_scrypt.cc b/src/crypto/crypto_scrypt.cc +index 4dae07f1..99a6a0e7 100644 +--- a/src/crypto/crypto_scrypt.cc ++++ b/src/crypto/crypto_scrypt.cc +@@ -114,10 +114,10 @@ Maybe ScryptTraits::AdditionalConfig( + return Just(true); + } + +-bool ScryptTraits::DeriveBits( +- Environment* env, +- const ScryptConfig& params, +- ByteSource* out) { ++bool ScryptTraits::DeriveBits(Environment* env, ++ const ScryptConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode) { + ByteSource::Builder buf(params.length); + + // Both the pass and salt may be zero-length at this point +diff --git a/src/crypto/crypto_scrypt.h b/src/crypto/crypto_scrypt.h +index 3d185637..9ea9d75d 100644 +--- a/src/crypto/crypto_scrypt.h ++++ b/src/crypto/crypto_scrypt.h +@@ -57,10 +57,10 @@ struct ScryptTraits final { + unsigned int offset, + ScryptConfig* params); + +- static bool DeriveBits( +- Environment* env, +- const ScryptConfig& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const ScryptConfig& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_sig.cc b/src/crypto/crypto_sig.cc +index ab020efb..b84fd3b7 100644 +--- a/src/crypto/crypto_sig.cc ++++ b/src/crypto/crypto_sig.cc +@@ -706,11 +706,11 @@ Maybe SignTraits::AdditionalConfig( + return Just(true); + } + +-bool SignTraits::DeriveBits( +- Environment* env, +- const SignConfiguration& params, +- ByteSource* out) { +- ClearErrorOnReturn clear_error_on_return; ++bool SignTraits::DeriveBits(Environment* env, ++ const SignConfiguration& params, ++ ByteSource* out, ++ CryptoJobMode mode) { ++ bool can_throw = mode == CryptoJobMode::kCryptoJobSync; + EVPMDCtxPointer context(EVP_MD_CTX_new()); + EVP_PKEY_CTX* ctx = nullptr; + +@@ -722,7 +722,7 @@ bool SignTraits::DeriveBits( + params.digest, + nullptr, + params.key.get())) { +- crypto::CheckThrow(env, SignBase::Error::kSignInit); ++ if (can_throw) crypto::CheckThrow(env, SignBase::Error::kSignInit); + return false; + } + break; +@@ -733,7 +733,7 @@ bool SignTraits::DeriveBits( + params.digest, + nullptr, + params.key.get())) { +- crypto::CheckThrow(env, SignBase::Error::kSignInit); ++ if (can_throw) crypto::CheckThrow(env, SignBase::Error::kSignInit); + return false; + } + break; +@@ -751,7 +751,7 @@ bool SignTraits::DeriveBits( + ctx, + padding, + salt_length)) { +- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); ++ if (can_throw) crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); + return false; + } + +@@ -765,7 +765,8 @@ bool SignTraits::DeriveBits( + &len, + params.data.data(), + params.data.size())) { +- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); ++ if (can_throw) ++ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); + return false; + } + ByteSource::Builder buf(len); +@@ -774,7 +775,8 @@ bool SignTraits::DeriveBits( + &len, + params.data.data(), + params.data.size())) { +- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); ++ if (can_throw) ++ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); + return false; + } + *out = std::move(buf).release(len); +@@ -785,13 +787,15 @@ bool SignTraits::DeriveBits( + params.data.data(), + params.data.size()) || + !EVP_DigestSignFinal(context.get(), nullptr, &len)) { +- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); ++ if (can_throw) ++ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); + return false; + } + ByteSource::Builder buf(len); + if (!EVP_DigestSignFinal( + context.get(), buf.data(), &len)) { +- crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); ++ if (can_throw) ++ crypto::CheckThrow(env, SignBase::Error::kSignPrivateKey); + return false; + } + +diff --git a/src/crypto/crypto_sig.h b/src/crypto/crypto_sig.h +index 63320147..3b2801fa 100644 +--- a/src/crypto/crypto_sig.h ++++ b/src/crypto/crypto_sig.h +@@ -147,10 +147,10 @@ struct SignTraits final { + unsigned int offset, + SignConfiguration* params); + +- static bool DeriveBits( +- Environment* env, +- const SignConfiguration& params, +- ByteSource* out); ++ static bool DeriveBits(Environment* env, ++ const SignConfiguration& params, ++ ByteSource* out, ++ CryptoJobMode mode); + + static v8::Maybe EncodeOutput( + Environment* env, +diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h +index 0ae2946e..260df59d 100644 +--- a/src/crypto/crypto_util.h ++++ b/src/crypto/crypto_util.h +@@ -498,9 +498,10 @@ class DeriveBitsJob final : public CryptoJob { + std::move(params)) {} + + void DoThreadPoolWork() override { ++ ClearErrorOnReturn clear_error_on_return; + if (!DeriveBitsTraits::DeriveBits( + AsyncWrap::env(), +- *CryptoJob::params(), &out_)) { ++ *CryptoJob::params(), &out_, this->mode())) { + CryptoErrorStore* errors = CryptoJob::errors(); + errors->Capture(); + if (errors->Empty()) +diff --git a/test/parallel/test-crypto-async-sign-verify.js b/test/parallel/test-crypto-async-sign-verify.js +index 4e3c32fd..5924d36e 100644 +--- a/test/parallel/test-crypto-async-sign-verify.js ++++ b/test/parallel/test-crypto-async-sign-verify.js +@@ -141,3 +141,29 @@ test('dsa_public.pem', 'dsa_private.pem', 'sha256', false, + }) + .catch(common.mustNotCall()); + } ++ ++{ ++ const untrustedKey = `-----BEGIN PUBLIC KEY----- ++MCowBQYDK2VuAyEA6pwGRbadNQAI/tYN8+/p/0/hbsdHfOEGr1ADiLVk/Gc= ++-----END PUBLIC KEY-----`; ++ const data = crypto.randomBytes(32); ++ const signature = crypto.randomBytes(16); ++ ++ const expected = common.hasOpenSSL3 ? ++ /operation not supported for this keytype/ : /no default digest/; ++ ++ crypto.verify(undefined, data, untrustedKey, signature, common.mustCall((err) => { ++ assert.ok(err); ++ assert.match(err.message, expected); ++ })); ++} ++ ++{ ++ const { privateKey } = crypto.generateKeyPairSync('rsa', { ++ modulusLength: 512 ++ }); ++ crypto.sign('sha512', 'message', privateKey, common.mustCall((err) => { ++ assert.ok(err); ++ assert.match(err.message, /digest too big for rsa key/); ++ })); ++} +-- +2.34.1 + diff --git a/SPECS/nodejs/CVE-2025-47279.patch b/SPECS/nodejs/CVE-2025-47279.patch new file mode 100644 index 00000000000..32e733d8519 --- /dev/null +++ b/SPECS/nodejs/CVE-2025-47279.patch @@ -0,0 +1,39 @@ +From 65cefbb3615e056330686cf5ffd1f7201fd8db58 Mon Sep 17 00:00:00 2001 +From: Aninda +Date: Mon, 19 May 2025 20:44:26 -0400 +Subject: [PATCH] Address CVE-2025-47279 +Upstream Patch Reference: https://github.com/nodejs/undici/commit/f317618ec28753a4218beccea048bcf89c36db25 + +--- + deps/undici/src/lib/dispatcher/pool.js | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +diff --git a/deps/undici/src/lib/dispatcher/pool.js b/deps/undici/src/lib/dispatcher/pool.js +index 0ba3a2b5..8cea1476 100644 +--- a/deps/undici/src/lib/dispatcher/pool.js ++++ b/deps/undici/src/lib/dispatcher/pool.js +@@ -73,6 +73,21 @@ class Pool extends PoolBase { + ? { ...options.interceptors } + : undefined + this[kFactory] = factory ++ ++ this.on('connectionError', (origin, targets, error) => { ++ // If a connection error occurs, we remove the client from the pool, ++ // and emit a connectionError event. They will not be re-used. ++ // Fixes https://github.com/nodejs/undici/issues/3895 ++ for (const target of targets) { ++ // Do not use kRemoveClient here, as it will close the client, ++ // but the client cannot be closed in this state. ++ const idx = this[kClients].indexOf(target) ++ if (idx !== -1) { ++ this[kClients].splice(idx, 1) ++ } ++ } ++ }) ++ + } + + [kGetDispatcher] () { +-- +2.34.1 + diff --git a/SPECS/nodejs/CVE-2025-5222.patch b/SPECS/nodejs/CVE-2025-5222.patch new file mode 100644 index 00000000000..73e82d48541 --- /dev/null +++ b/SPECS/nodejs/CVE-2025-5222.patch @@ -0,0 +1,164 @@ +From 87e1ef3c27772750cf717253738886a1c04b7b29 Mon Sep 17 00:00:00 2001 +From: Frank Tang +Date: Wed, 22 Jan 2025 11:50:59 -0800 +Subject: [PATCH] ICU-22973 Fix buffer overflow by using CharString + +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://github.com/unicode-org/icu/commit/2c667e31cfd0b6bb1923627a932fd3453a5bac77.patch +--- + deps/icu-small/source/tools/genrb/parse.cpp | 49 ++++++++++++--------- + 1 file changed, 29 insertions(+), 20 deletions(-) + +diff --git a/deps/icu-small/source/tools/genrb/parse.cpp b/deps/icu-small/source/tools/genrb/parse.cpp +index a6c59948..799a2241 100644 +--- a/deps/icu-small/source/tools/genrb/parse.cpp ++++ b/deps/icu-small/source/tools/genrb/parse.cpp +@@ -1153,7 +1153,7 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp + struct UString *tokenValue; + struct UString comment; + enum ETokenType token; +- char subtag[1024]; ++ CharString subtag; + UnicodeString rules; + UBool haveRules = false; + UVersionInfo version; +@@ -1189,15 +1189,15 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp + return nullptr; + } + +- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); +- ++ subtag.clear(); ++ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); + if (U_FAILURE(*status)) + { + res_close(result); + return nullptr; + } + +- member = parseResource(state, subtag, nullptr, status); ++ member = parseResource(state, subtag.data(), nullptr, status); + + if (U_FAILURE(*status)) + { +@@ -1208,7 +1208,7 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp + { + // Ignore the parsed resources, continue parsing. + } +- else if (uprv_strcmp(subtag, "Version") == 0 && member->isString()) ++ else if (uprv_strcmp(subtag.data(), "Version") == 0 && member->isString()) + { + StringResource *sr = static_cast(member); + char ver[40]; +@@ -1225,11 +1225,11 @@ addCollation(ParseState* state, TableResource *result, const char *collationTyp + result->add(member, line, *status); + member = nullptr; + } +- else if(uprv_strcmp(subtag, "%%CollationBin")==0) ++ else if(uprv_strcmp(subtag.data(), "%%CollationBin")==0) + { + /* discard duplicate %%CollationBin if any*/ + } +- else if (uprv_strcmp(subtag, "Sequence") == 0 && member->isString()) ++ else if (uprv_strcmp(subtag.data(), "Sequence") == 0 && member->isString()) + { + StringResource *sr = static_cast(member); + rules = sr->fString; +@@ -1395,7 +1395,7 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n + struct UString *tokenValue; + struct UString comment; + enum ETokenType token; +- char subtag[1024], typeKeyword[1024]; ++ CharString subtag, typeKeyword; + uint32_t line; + + result = table_open(state->bundle, tag, nullptr, status); +@@ -1437,7 +1437,8 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n + return nullptr; + } + +- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); ++ subtag.clear(); ++ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); + + if (U_FAILURE(*status)) + { +@@ -1445,9 +1446,9 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n + return nullptr; + } + +- if (uprv_strcmp(subtag, "default") == 0) ++ if (uprv_strcmp(subtag.data(), "default") == 0) + { +- member = parseResource(state, subtag, nullptr, status); ++ member = parseResource(state, subtag.data(), nullptr, status); + + if (U_FAILURE(*status)) + { +@@ -1466,22 +1467,29 @@ parseCollationElements(ParseState* state, char *tag, uint32_t startline, UBool n + if(token == TOK_OPEN_BRACE) { + token = getToken(state, &tokenValue, &comment, &line, status); + TableResource *collationRes; +- if (keepCollationType(subtag)) { +- collationRes = table_open(state->bundle, subtag, nullptr, status); ++ if (keepCollationType(subtag.data())) { ++ collationRes = table_open(state->bundle, subtag.data(), nullptr, status); + } else { + collationRes = nullptr; + } + // need to parse the collation data regardless +- collationRes = addCollation(state, collationRes, subtag, startline, status); ++ collationRes = addCollation(state, collationRes, subtag.data(), startline, status); + if (collationRes != nullptr) { + result->add(collationRes, startline, *status); + } + } else if(token == TOK_COLON) { /* right now, we'll just try to see if we have aliases */ + /* we could have a table too */ + token = peekToken(state, 1, &tokenValue, &line, &comment, status); +- u_UCharsToChars(tokenValue->fChars, typeKeyword, u_strlen(tokenValue->fChars) + 1); +- if(uprv_strcmp(typeKeyword, "alias") == 0) { +- member = parseResource(state, subtag, nullptr, status); ++ typeKeyword.clear(); ++ typeKeyword.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); ++ if (U_FAILURE(*status)) ++ { ++ res_close(result); ++ return nullptr; ++ } ++ ++ if(uprv_strcmp(typeKeyword.data(), "alias") == 0) { ++ member = parseResource(state, subtag.data(), nullptr, status); + if (U_FAILURE(*status)) + { + res_close(result); +@@ -1523,7 +1531,7 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star + struct UString *tokenValue=nullptr; + struct UString comment; + enum ETokenType token; +- char subtag[1024]; ++ CharString subtag; + uint32_t line; + UBool readToken = false; + +@@ -1562,7 +1570,8 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star + } + + if(uprv_isInvariantUString(tokenValue->fChars, -1)) { +- u_UCharsToChars(tokenValue->fChars, subtag, u_strlen(tokenValue->fChars) + 1); ++ subtag.clear(); ++ subtag.appendInvariantChars(tokenValue->fChars, u_strlen(tokenValue->fChars), *status); + } else { + *status = U_INVALID_FORMAT_ERROR; + error(line, "invariant characters required for table keys"); +@@ -1575,7 +1584,7 @@ realParseTable(ParseState* state, TableResource *table, char *tag, uint32_t star + return nullptr; + } + +- member = parseResource(state, subtag, &comment, status); ++ member = parseResource(state, subtag.data(), &comment, status); + + if (member == nullptr || U_FAILURE(*status)) + { +-- +2.45.4 + diff --git a/SPECS/nodejs/nodejs.signatures.json b/SPECS/nodejs/nodejs.signatures.json index 5078533f52d..1aae9452d70 100644 --- a/SPECS/nodejs/nodejs.signatures.json +++ b/SPECS/nodejs/nodejs.signatures.json @@ -1,8 +1,5 @@ { - "Signatures": { - "btest402.js": "fabaf4dacc13e93d54f825b87ffde18573214b149388a5f96176236dd31d7768", - "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", - "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", - "node-v24.12.0.tar.xz": "3541292851cb97d0e31b7b4943863c442f670a1af0534b3d8fa928aa1cc633b9" - } -} \ No newline at end of file + "Signatures": { + "node-v20.14.0.tar.xz": "1f5d3dc55f968f5141410b301303e11612c1c407402683eb3026d722b52fd37e" + } +} diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index cf37de8286b..6b80ae56ff7 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -1,22 +1,11 @@ # Retrieved from 'deps/npm/package.json' inside the sources tarball. -%define npm_version 11.6.2 - -%global nodejs_datadir %{_datarootdir}/nodejs - -# ICU - from tools/icu/current_ver.dep -%global icu_major 77 -%global icu_minor 1 -%global icu_version %{icu_major}.%{icu_minor} - -%global icudatadir %{nodejs_datadir}/icudata -%{!?little_endian: %global little_endian %(%{python3} -c "import sys;print (0 if sys.byteorder=='big' else 1)")} - +%define npm_version 10.7.0 Summary: A JavaScript runtime built on Chrome's V8 JavaScript engine. Name: nodejs # WARNINGS: MUST check and update the 'npm_version' macro for every version update of this package. # The version of NPM can be found inside the sources under 'deps/npm/package.json'. -Version: 24.12.0 -Release: 1%{?dist} +Version: 20.14.0 +Release: 10%{?dist} License: BSD AND MIT AND Public Domain AND NAIST-2003 AND Artistic-2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -26,15 +15,21 @@ URL: https://github.com/nodejs/node # !!!! because it contains patented algorithms. # !!! => use generate_source_tarball.sh script to create a clean and reproducible source tarball. Source0: https://nodejs.org/download/release/v%{version}/node-v%{version}.tar.xz -Source1: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-b.zip -Source2: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-l.zip -Source3: btest402.js Patch0: disable-tlsv1-tlsv1-1.patch Patch1: CVE-2019-10906.patch -Patch2: CVE-2024-22195.patch -Patch3: CVE-2020-28493.patch -Patch4: CVE-2024-34064.patch -Patch5: CVE-2025-27516.patch +Patch2: CVE-2024-21538.patch +Patch3: CVE-2025-23083.patch +Patch4: CVE-2025-22150.patch +Patch5: CVE-2025-23085.patch +Patch6: CVE-2024-22020.patch +Patch7: CVE-2024-22195.patch +Patch8: CVE-2020-28493.patch +Patch9: CVE-2024-34064.patch +Patch10: CVE-2025-27516.patch +Patch11: CVE-2025-47279.patch +Patch12: CVE-2025-23165.patch +Patch13: CVE-2025-23166.patch +Patch14: CVE-2025-5222.patch BuildRequires: brotli-devel BuildRequires: c-ares-devel BuildRequires: coreutils >= 8.22 @@ -50,9 +45,6 @@ Requires: c-ares Requires: coreutils >= 8.22 Requires: openssl >= 1.1.1 -Recommends: nodejs-full-i18n = %{version}-%{release} -Provides: bundled(icu) = %{icu_version} - %description Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. @@ -70,14 +62,6 @@ Requires: zlib-devel The nodejs-devel package contains libraries, header files and documentation for developing applications that use nodejs. -%package full-i18n -Summary: Non-English locale data for Node.js -Requires: %{name} = %{version}-%{release} - -%description full-i18n -Optional data files to provide full-icu support for Node.js. Remove this -package to save space if non-English locales are not needed. - %package npm Summary: Node.js Package Manager Group: System Environment/Base @@ -114,7 +98,6 @@ python3 configure.py \ --shared-brotli \ --with-intl=small-icu \ --with-icu-source=deps/icu-small \ - --with-icu-default-data-dir=%{icudatadir} \ --openssl-use-def-ca-store \ --shared-cares @@ -132,18 +115,7 @@ for FILE in .gitmodules .gitignore .npmignore .travis.yml \*.py[co]; do find %{buildroot}%{_libdir}/node_modules/ -name "$FILE" -delete done -# Install the full-icu data files -mkdir -p %{buildroot}%{icudatadir} -%if 0%{?little_endian} -unzip -d %{buildroot}%{icudatadir} %{SOURCE2} icudt%{icu_major}l.dat -%else -unzip -d %{buildroot}%{icudatadir} %{SOURCE1} icudt%{icu_major}b.dat -%endif - %check -# Make sure i18n support is working -NODE_PATH=%{buildroot}%{_prefix}/lib/node_modules:%{buildroot}%{_prefix}/lib/node_modules/npm/node_modules LD_LIBRARY_PATH=%{buildroot}%{_libdir} %{buildroot}/%{_bindir}/node --icu-data-dir=%{buildroot}%{icudatadir} %{SOURCE3} - make cctest %post -p /sbin/ldconfig @@ -161,10 +133,6 @@ make cctest %{_includedir}/* %{_docdir}/* -%files full-i18n -%dir %{icudatadir} -%{icudatadir}/icudt%{icu_major}*.dat - %files npm %defattr(-,root,root) %{_bindir}/npm @@ -173,10 +141,6 @@ make cctest %{_prefix}/lib/node_modules/* %changelog -* Tue Dec 23 2025 Sandeep Karambelkar - 24.12.0-1 -- Upgrade to 24.12.0 -- Add support for passing runtime internationalization data - * Fri Nov 07 2025 Azure Linux Security Servicing Account - 20.14.0-10 - Patch for CVE-2025-5222 diff --git a/SPECS/nodejs24/CVE-2019-10906.patch b/SPECS/nodejs24/CVE-2019-10906.patch new file mode 100644 index 00000000000..e4aca456fc5 --- /dev/null +++ b/SPECS/nodejs24/CVE-2019-10906.patch @@ -0,0 +1,197 @@ +From ce71e5f5911b12ebc36711a7d86dab0a11bd1c4d Mon Sep 17 00:00:00 2001 +From: Suresh Thelkar +Date: Fri, 20 Sep 2024 09:55:21 +0530 +Subject: [PATCH] Changed needed to upgrade jinja2 to 2.10.1 + +--- + .../jinja2/Jinja2-2.10.1.tar.gz.md5 | 1 + + .../jinja2/Jinja2-2.10.1.tar.gz.sha512 | 1 + + .../jinja2/Jinja2-2.10.tar.gz.md5 | 1 - + .../jinja2/Jinja2-2.10.tar.gz.sha512 | 1 - + tools/inspector_protocol/jinja2/LICENSE | 62 +++++++++---------- + tools/inspector_protocol/jinja2/__init__.py | 2 +- + tools/inspector_protocol/jinja2/get_jinja2.sh | 4 +- + tools/inspector_protocol/jinja2/sandbox.py | 17 ++++- + 8 files changed, 50 insertions(+), 39 deletions(-) + create mode 100644 tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.md5 + create mode 100644 tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.sha512 + delete mode 100644 tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.md5 + delete mode 100644 tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.sha512 + +diff --git a/tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.md5 b/tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.md5 +new file mode 100644 +index 00000000..254f4371 +--- /dev/null ++++ b/tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.md5 +@@ -0,0 +1 @@ ++0ae535be40fd215a8114a090c8b68e5a Jinja2-2.10.1.tar.gz +\ No newline at end of file +diff --git a/tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.sha512 b/tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.sha512 +new file mode 100644 +index 00000000..7c379ff1 +--- /dev/null ++++ b/tools/inspector_protocol/jinja2/Jinja2-2.10.1.tar.gz.sha512 +@@ -0,0 +1 @@ ++a00153a0e07bb7d67f301b4eaf7af657726a1985e9ffc7ae2d76bdbb4c062d672efc8065e398767e1039b18a483a0092e206deac91e4047aad64920b56869623 Jinja2-2.10.1.tar.gz +\ No newline at end of file +diff --git a/tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.md5 b/tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.md5 +deleted file mode 100644 +index 9137ee12..00000000 +--- a/tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.md5 ++++ /dev/null +@@ -1 +0,0 @@ +-61ef1117f945486472850819b8d1eb3d Jinja2-2.10.tar.gz +diff --git a/tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.sha512 b/tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.sha512 +deleted file mode 100644 +index 087d24c1..00000000 +--- a/tools/inspector_protocol/jinja2/Jinja2-2.10.tar.gz.sha512 ++++ /dev/null +@@ -1 +0,0 @@ +-0ea7371be67ffcf19e46dfd06523a45a0806e678a407d54f5f2f3e573982f0959cf82ec5d07b203670309928a62ef71109701ab16547a9bba2ebcdc178cb67f2 Jinja2-2.10.tar.gz +diff --git a/tools/inspector_protocol/jinja2/LICENSE b/tools/inspector_protocol/jinja2/LICENSE +index 31bf900e..10145a26 100644 +--- a/tools/inspector_protocol/jinja2/LICENSE ++++ b/tools/inspector_protocol/jinja2/LICENSE +@@ -1,31 +1,31 @@ +-Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. +- +-Some rights reserved. +- +-Redistribution and use in source and binary forms, with or without +-modification, are permitted provided that the following conditions are +-met: +- +- * Redistributions of source code must retain the above copyright +- notice, this list of conditions and the following disclaimer. +- +- * Redistributions in binary form must reproduce the above +- copyright notice, this list of conditions and the following +- disclaimer in the documentation and/or other materials provided +- with the distribution. +- +- * The names of the contributors may not be used to endorse or +- promote products derived from this software without specific +- prior written permission. +- +-THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +-"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +-LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +-A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +-OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +-SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +-LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +-DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +-THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +-(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +-OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ++Copyright (c) 2009 by the Jinja Team, see AUTHORS for more details. ++ ++Some rights reserved. ++ ++Redistribution and use in source and binary forms, with or without ++modification, are permitted provided that the following conditions are ++met: ++ ++ * Redistributions of source code must retain the above copyright ++ notice, this list of conditions and the following disclaimer. ++ ++ * Redistributions in binary form must reproduce the above ++ copyright notice, this list of conditions and the following ++ disclaimer in the documentation and/or other materials provided ++ with the distribution. ++ ++ * The names of the contributors may not be used to endorse or ++ promote products derived from this software without specific ++ prior written permission. ++ ++THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ++"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT ++LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR ++A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT ++OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, ++SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT ++LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, ++DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY ++THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ++(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE ++OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +diff --git a/tools/inspector_protocol/jinja2/__init__.py b/tools/inspector_protocol/jinja2/__init__.py +index 42aa763d..15e13b6f 100644 +--- a/tools/inspector_protocol/jinja2/__init__.py ++++ b/tools/inspector_protocol/jinja2/__init__.py +@@ -27,7 +27,7 @@ + :license: BSD, see LICENSE for more details. + """ + __docformat__ = 'restructuredtext en' +-__version__ = '2.10' ++__version__ = '2.10.1' + + # high level interface + from jinja2.environment import Environment, Template +diff --git a/tools/inspector_protocol/jinja2/get_jinja2.sh b/tools/inspector_protocol/jinja2/get_jinja2.sh +index bc6c4c30..b0fa6e8e 100755 +--- a/tools/inspector_protocol/jinja2/get_jinja2.sh ++++ b/tools/inspector_protocol/jinja2/get_jinja2.sh +@@ -7,8 +7,8 @@ + # Download page: + # https://pypi.python.org/pypi/Jinja2 + PACKAGE='Jinja2' +-VERSION='2.10' +-SRC_URL='https://pypi.python.org/packages/56/e6/332789f295cf22308386cf5bbd1f4e00ed11484299c5d7383378cf48ba47/Jinja2-2.10.tar.gz' ++VERSION='2.10.1' ++SRC_URL='https://files.pythonhosted.org/packages/93/ea/d884a06f8c7f9b7afbc8138b762e80479fb17aedbbe2b06515a12de9378d/Jinja2-2.10.1.tar.gz' + PACKAGE_DIR='jinja2' + + CHROMIUM_FILES="README.chromium OWNERS get_jinja2.sh" +diff --git a/tools/inspector_protocol/jinja2/sandbox.py b/tools/inspector_protocol/jinja2/sandbox.py +index 93fb9d45..752e8128 100644 +--- a/tools/inspector_protocol/jinja2/sandbox.py ++++ b/tools/inspector_protocol/jinja2/sandbox.py +@@ -137,7 +137,7 @@ class _MagicFormatMapping(Mapping): + def inspect_format_method(callable): + if not isinstance(callable, (types.MethodType, + types.BuiltinMethodType)) or \ +- callable.__name__ != 'format': ++ callable.__name__ not in ('format', 'format_map'): + return None + obj = callable.__self__ + if isinstance(obj, string_types): +@@ -402,7 +402,7 @@ class SandboxedEnvironment(Environment): + obj.__class__.__name__ + ), name=attribute, obj=obj, exc=SecurityError) + +- def format_string(self, s, args, kwargs): ++ def format_string(self, s, args, kwargs, format_func=None): + """If a format call is detected, then this is routed through this + method so that our safety sandbox can be used for it. + """ +@@ -410,6 +410,17 @@ class SandboxedEnvironment(Environment): + formatter = SandboxedEscapeFormatter(self, s.escape) + else: + formatter = SandboxedFormatter(self) ++ ++ if format_func is not None and format_func.__name__ == 'format_map': ++ if len(args) != 1 or kwargs: ++ raise TypeError( ++ 'format_map() takes exactly one argument %d given' ++ % (len(args) + (kwargs is not None)) ++ ) ++ ++ kwargs = args[0] ++ args = None ++ + kwargs = _MagicFormatMapping(args, kwargs) + rv = formatter.vformat(s, args, kwargs) + return type(s)(rv) +@@ -418,7 +429,7 @@ class SandboxedEnvironment(Environment): + """Call an object from sandboxed code.""" + fmt = inspect_format_method(__obj) + if fmt is not None: +- return __self.format_string(fmt, args, kwargs) ++ return __self.format_string(fmt, args, kwargs, __obj) + + # the double prefixes are to avoid double keyword argument + # errors when proxying the call. +-- +2.34.1 + diff --git a/SPECS/nodejs24/CVE-2020-28493.patch b/SPECS/nodejs24/CVE-2020-28493.patch new file mode 100644 index 00000000000..c7ea9c4129b --- /dev/null +++ b/SPECS/nodejs24/CVE-2020-28493.patch @@ -0,0 +1,134 @@ +From 1416131a2c937e08dd313f622f6c8b928c64e477 Mon Sep 17 00:00:00 2001 +From: Kevin Lockwood +Date: Wed, 5 Feb 2025 16:33:58 -0800 +Subject: [PATCH] [Medium] Patch nodejs to fix CVE-2020-28493 + +Link: https://github.com/pallets/jinja/pull/1343/commits/ef658dc3b6389b091d608e710a810ce8b87995b3.patch +--- + tools/inspector_protocol/jinja2/utils.py | 93 ++++++++++++++---------- + 1 file changed, 56 insertions(+), 37 deletions(-) + +diff --git a/tools/inspector_protocol/jinja2/utils.py b/tools/inspector_protocol/jinja2/utils.py +index 502a311c..00664b56 100644 +--- a/tools/inspector_protocol/jinja2/utils.py ++++ b/tools/inspector_protocol/jinja2/utils.py +@@ -12,24 +12,13 @@ import re + import json + import errno + from collections import deque ++from string import ascii_letters as _letters ++from string import digits as _digits + from threading import Lock + from jinja2._compat import text_type, string_types, implements_iterator, \ + url_quote + + +-_word_split_re = re.compile(r'(\s+)') +-_punctuation_re = re.compile( +- '^(?P(?:%s)*)(?P.*?)(?P(?:%s)*)$' % ( +- '|'.join(map(re.escape, ('(', '<', '<'))), +- '|'.join(map(re.escape, ('.', ',', ')', '>', '\n', '>'))) +- ) +-) +-_simple_email_re = re.compile(r'^\S+@[a-zA-Z0-9._-]+\.[a-zA-Z0-9._-]+$') +-_striptags_re = re.compile(r'(|<[^>]*>)') +-_entity_re = re.compile(r'&([^;]+);') +-_letters = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ' +-_digits = '0123456789' +- + # special singleton representing missing values for the runtime + missing = type('MissingType', (), {'__repr__': lambda x: 'missing'})() + +@@ -203,35 +192,65 @@ def urlize(text, trim_url_limit=None, rel=None, target=None): + trim_url = lambda x, limit=trim_url_limit: limit is not None \ + and (x[:limit] + (len(x) >=limit and '...' + or '')) or x +- words = _word_split_re.split(text_type(escape(text))) ++ words = re.split(r"(\s+)", text_type(escape(text))) + rel_attr = rel and ' rel="%s"' % text_type(escape(rel)) or '' + target_attr = target and ' target="%s"' % escape(target) or '' + + for i, word in enumerate(words): +- match = _punctuation_re.match(word) ++ head, middle, tail = "", word, "" ++ match = re.match(r"^([(<]|<)+", middle) ++ + if match: +- lead, middle, trail = match.groups() +- if middle.startswith('www.') or ( +- '@' not in middle and +- not middle.startswith('http://') and +- not middle.startswith('https://') and +- len(middle) > 0 and +- middle[0] in _letters + _digits and ( +- middle.endswith('.org') or +- middle.endswith('.net') or +- middle.endswith('.com') +- )): +- middle = '%s' % (middle, +- rel_attr, target_attr, trim_url(middle)) +- if middle.startswith('http://') or \ +- middle.startswith('https://'): +- middle = '%s' % (middle, +- rel_attr, target_attr, trim_url(middle)) +- if '@' in middle and not middle.startswith('www.') and \ +- not ':' in middle and _simple_email_re.match(middle): +- middle = '%s' % (middle, middle) +- if lead + middle + trail != word: +- words[i] = lead + middle + trail ++ head = match.group() ++ middle = middle[match.end() :] ++ ++ # Unlike lead, which is anchored to the start of the string, ++ # need to check that the string ends with any of the characters ++ # before trying to match all of them, to avoid backtracking. ++ if middle.endswith((")", ">", ".", ",", "\n", ">")): ++ match = re.search(r"([)>.,\n]|>)+$", middle) ++ ++ if match: ++ tail = match.group() ++ middle = middle[: match.start()] ++ ++ if middle.startswith("www.") or ( ++ "@" not in middle ++ and not middle.startswith("http://") ++ and not middle.startswith("https://") ++ and len(middle) > 0 ++ and middle[0] in _letters + _digits ++ and ( ++ middle.endswith(".org") ++ or middle.endswith(".net") ++ or middle.endswith(".com") ++ ) ++ ): ++ middle = '%s' % ( ++ middle, ++ rel_attr, ++ target_attr, ++ trim_url(middle), ++ ) ++ ++ if middle.startswith("http://") or middle.startswith("https://"): ++ middle = '%s' % ( ++ middle, ++ rel_attr, ++ target_attr, ++ trim_url(middle), ++ ) ++ ++ if ( ++ "@" in middle ++ and not middle.startswith("www.") ++ and ":" not in middle ++ and re.match(r"^\S+@\w[\w.-]*\.\w+$", middle) ++ ): ++ middle = '%s' % (middle, middle) ++ ++ words[i] = head + middle + tail ++ + return u''.join(words) + + +-- +2.34.1 + diff --git a/SPECS/nodejs24/CVE-2024-22195.patch b/SPECS/nodejs24/CVE-2024-22195.patch new file mode 100644 index 00000000000..eddb8a6f92e --- /dev/null +++ b/SPECS/nodejs24/CVE-2024-22195.patch @@ -0,0 +1,64 @@ +From 7150425bb9ea718fc9a8007ab3ba6a421f97e0a6 Mon Sep 17 00:00:00 2001 +From: Kanishk-Bansal +Date: Wed, 12 Feb 2025 05:35:22 +0000 +Subject: [PATCH] Fix CVE-2024-22195 + +--- + deps/v8/third_party/jinja2/filters.py | 28 ++++++++++++++++++++------- + 1 file changed, 21 insertions(+), 7 deletions(-) + +diff --git a/deps/v8/third_party/jinja2/filters.py b/deps/v8/third_party/jinja2/filters.py +index ed07c4c0..c7ecc9bb 100644 +--- a/deps/v8/third_party/jinja2/filters.py ++++ b/deps/v8/third_party/jinja2/filters.py +@@ -248,13 +248,17 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K + yield from value.items() + + ++_space_re = re.compile(r"\s", flags=re.ASCII) ++ ++ + @pass_eval_context + def do_xmlattr( + eval_ctx: "EvalContext", d: t.Mapping[str, t.Any], autospace: bool = True + ) -> str: + """Create an SGML/XML attribute string based on the items in a dict. +- All values that are neither `none` nor `undefined` are automatically +- escaped: ++ ++ If any key contains a space, this fails with a ``ValueError``. Values that ++ are neither ``none`` nor ``undefined`` are automatically escaped. + + .. sourcecode:: html+jinja + +@@ -273,12 +277,22 @@ def do_xmlattr( + + As you can see it automatically prepends a space in front of the item + if the filter returned something unless the second parameter is false. ++ ++ .. versionchanged:: 3.1.3 ++ Keys with spaces are not allowed. + """ +- rv = " ".join( +- f'{escape(key)}="{escape(value)}"' +- for key, value in d.items() +- if value is not None and not isinstance(value, Undefined) +- ) ++ items = [] ++ ++ for key, value in d.items(): ++ if value is None or isinstance(value, Undefined): ++ continue ++ ++ if _space_re.search(key) is not None: ++ raise ValueError(f"Spaces are not allowed in attributes: '{key}'") ++ ++ items.append(f'{escape(key)}="{escape(value)}"') ++ ++ rv = " ".join(items) + + if autospace and rv: + rv = " " + rv +-- +2.45.2 + diff --git a/SPECS/nodejs24/CVE-2024-34064.patch b/SPECS/nodejs24/CVE-2024-34064.patch new file mode 100644 index 00000000000..74f949e639f --- /dev/null +++ b/SPECS/nodejs24/CVE-2024-34064.patch @@ -0,0 +1,68 @@ +From 7d26e047cce618fe6e8ccb26bf3d4685d4a7815e Mon Sep 17 00:00:00 2001 +From: Kevin Lockwood +Date: Thu, 3 Apr 2025 12:04:25 -0700 +Subject: [PATCH] [Medium] Patch nodejs for CVE-2024-34064 + +--- + deps/v8/third_party/jinja2/filters.py | 24 +++++++++++++++++++----- + 1 file changed, 19 insertions(+), 5 deletions(-) + +diff --git a/deps/v8/third_party/jinja2/filters.py b/deps/v8/third_party/jinja2/filters.py +index c7ecc9bb..eace6ed8 100644 +--- a/deps/v8/third_party/jinja2/filters.py ++++ b/deps/v8/third_party/jinja2/filters.py +@@ -248,7 +248,10 @@ def do_items(value: t.Union[t.Mapping[K, V], Undefined]) -> t.Iterator[t.Tuple[K + yield from value.items() + + +-_space_re = re.compile(r"\s", flags=re.ASCII) ++# Check for characters that would move the parser state from key to value. ++# https://html.spec.whatwg.org/#attribute-name-state ++_attr_key_re = re.compile(r"[\s/>=]", flags=re.ASCII) ++ + + + @pass_eval_context +@@ -257,8 +260,14 @@ def do_xmlattr( + ) -> str: + """Create an SGML/XML attribute string based on the items in a dict. + +- If any key contains a space, this fails with a ``ValueError``. Values that +- are neither ``none`` nor ``undefined`` are automatically escaped. ++ **Values** that are neither ``none`` nor ``undefined`` are automatically ++ escaped, safely allowing untrusted user input. ++ ++ User input should not be used as **keys** to this filter. If any key ++ contains a space, ``/`` solidus, ``>`` greater-than sign, or ``=`` equals ++ sign, this fails with a ``ValueError``. Regardless of this, user input ++ should never be used as keys to this filter, or must be separately validated ++ first. + + .. sourcecode:: html+jinja + +@@ -280,6 +289,11 @@ def do_xmlattr( + + .. versionchanged:: 3.1.3 + Keys with spaces are not allowed. ++ ++ .. versionchanged:: 3.1.4 ++ Keys with ``/`` solidus, ``>`` greater-than sign, or ``=`` equals sign ++ are not allowed. ++ + """ + items = [] + +@@ -287,8 +301,8 @@ def do_xmlattr( + if value is None or isinstance(value, Undefined): + continue + +- if _space_re.search(key) is not None: +- raise ValueError(f"Spaces are not allowed in attributes: '{key}'") ++ if _attr_key_re.search(key) is not None: ++ raise ValueError(f"Invalid character in attribute name: {key!r}") + + items.append(f'{escape(key)}="{escape(value)}"') + +-- +2.34.1 + diff --git a/SPECS/nodejs24/CVE-2025-27516.patch b/SPECS/nodejs24/CVE-2025-27516.patch new file mode 100644 index 00000000000..f29c39628f1 --- /dev/null +++ b/SPECS/nodejs24/CVE-2025-27516.patch @@ -0,0 +1,68 @@ +From 065334d1ee5b7210e1a0a93c37238c86858f2af7 Mon Sep 17 00:00:00 2001 +From: David Lord +Date: Wed, 5 Mar 2025 10:08:48 -0800 +Subject: [PATCH] attr filter uses env.getattr + +--- + deps/v8/third_party/jinja2/filters.py | 37 ++++++++++++++++--------------------- + 3 files changed, 30 insertions(+), 21 deletions(-) + +diff --git a/deps/v8/third_party/jinja2/filters.py b/deps/v8/third_party/jinja2/filters.py +index e5b5a00c5..2bcba4fbd 100644 +--- a/deps/v8/third_party/jinja2/filters.py ++++ b/deps/v8/third_party/jinja2/filters.py +@@ -6,6 +6,7 @@ + import typing + import typing as t + from collections import abc ++from inspect import getattr_static + from itertools import chain + from itertools import groupby + +@@ -1411,31 +1412,25 @@ def do_reverse(value: t.Union[str, t.Iterable[V]]) -> t.Union[str, t.Iterable[V] + def do_attr( + environment: "Environment", obj: t.Any, name: str + ) -> t.Union[Undefined, t.Any]: +- """Get an attribute of an object. ``foo|attr("bar")`` works like +- ``foo.bar`` just that always an attribute is returned and items are not +- looked up. ++ """Get an attribute of an object. ``foo|attr("bar")`` works like ++ ``foo.bar``, but returns undefined instead of falling back to ``foo["bar"]`` ++ if the attribute doesn't exist. + + See :ref:`Notes on subscriptions ` for more details. + """ ++ # Environment.getattr will fall back to obj[name] if obj.name doesn't exist. ++ # But we want to call env.getattr to get behavior such as sandboxing. ++ # Determine if the attr exists first, so we know the fallback won't trigger. + try: +- name = str(name) +- except UnicodeError: +- pass +- else: +- try: +- value = getattr(obj, name) +- except AttributeError: +- pass +- else: +- if environment.sandboxed: +- environment = t.cast("SandboxedEnvironment", environment) +- +- if not environment.is_safe_attribute(obj, name, value): +- return environment.unsafe_undefined(obj, name) +- +- return value +- +- return environment.undefined(obj=obj, name=name) ++ # This avoids executing properties/descriptors, but misses __getattr__ ++ # and __getattribute__ dynamic attrs. ++ getattr_static(obj, name) ++ except AttributeError: ++ # This finds dynamic attrs, and we know it's not a descriptor at this point. ++ if not hasattr(obj, name): ++ return environment.undefined(obj=obj, name=name) ++ ++ return environment.getattr(obj, name) + + + @typing.overload diff --git a/SPECS/nodejs/btest402.js b/SPECS/nodejs24/btest402.js similarity index 100% rename from SPECS/nodejs/btest402.js rename to SPECS/nodejs24/btest402.js diff --git a/SPECS/nodejs24/disable-tlsv1-tlsv1-1.patch b/SPECS/nodejs24/disable-tlsv1-tlsv1-1.patch new file mode 100644 index 00000000000..0a40760b4f7 --- /dev/null +++ b/SPECS/nodejs24/disable-tlsv1-tlsv1-1.patch @@ -0,0 +1,42 @@ +diff -ru node-v16.14.0-orig/src/crypto/crypto_context.cc node-v16.14.0/src/crypto/crypto_context.cc +--- node-v16.14.0-orig/src/crypto/crypto_context.cc 2022-02-08 04:37:50.000000000 -0800 ++++ node-v16.14.0/src/crypto/crypto_context.cc 2022-02-25 09:17:21.964960342 -0800 +@@ -467,28 +467,16 @@ + min_version = 0; + max_version = kMaxSupportedVersion; + method = TLS_client_method(); +- } else if (sslmethod == "TLSv1_method") { +- min_version = TLS1_VERSION; +- max_version = TLS1_VERSION; +- } else if (sslmethod == "TLSv1_server_method") { +- min_version = TLS1_VERSION; +- max_version = TLS1_VERSION; +- method = TLS_server_method(); +- } else if (sslmethod == "TLSv1_client_method") { +- min_version = TLS1_VERSION; +- max_version = TLS1_VERSION; +- method = TLS_client_method(); +- } else if (sslmethod == "TLSv1_1_method") { +- min_version = TLS1_1_VERSION; +- max_version = TLS1_1_VERSION; +- } else if (sslmethod == "TLSv1_1_server_method") { +- min_version = TLS1_1_VERSION; +- max_version = TLS1_1_VERSION; +- method = TLS_server_method(); +- } else if (sslmethod == "TLSv1_1_client_method") { +- min_version = TLS1_1_VERSION; +- max_version = TLS1_1_VERSION; +- method = TLS_client_method(); ++ } else if (sslmethod == "TLSv1_method" || ++ sslmethod == "TLSv1_server_method" || ++ sslmethod == "TLSv1_client_method") { ++ THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "TLSv1 methods disabled"); ++ return; ++ } else if (sslmethod == "TLSv1_1_method" || ++ sslmethod == "TLSv1_1_server_method" || ++ sslmethod == "TLSv1_1_client_method") { ++ THROW_ERR_TLS_INVALID_PROTOCOL_METHOD(env, "TLSv1_1 methods disabled"); ++ return; + } else if (sslmethod == "TLSv1_2_method") { + min_version = TLS1_2_VERSION; + max_version = TLS1_2_VERSION; diff --git a/SPECS/nodejs24/generate_source_tarball.sh b/SPECS/nodejs24/generate_source_tarball.sh new file mode 100755 index 00000000000..550ba1d444d --- /dev/null +++ b/SPECS/nodejs24/generate_source_tarball.sh @@ -0,0 +1,117 @@ +#!/bin/bash +# Copyright (c) Microsoft Corporation. +# Licensed under the MIT License. + +# Quit on failure +set -e + +# +# The nodejs source tarball contains a copy of the OpenSSL source tree. +# OpenSSL contains patented algorithms that should not be distributed +# as part of the SRPM. Since we use the shared OpenSSL libraries, we +# can just remove the entire OpenSSL source tree from the tarball. + +PKG_VERSION="" +SRC_TARBALL="" +OUT_FOLDER="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" + +# parameters: +# +# --srcTarball : src tarball file +# this file contains the 'initial' source code of the component +# and should be replaced with the new/modified src code +# --outFolder : folder where to copy the new tarball(s) +# --pkgVersion : package version +# +PARAMS="" +while (( "$#" )); do + case "$1" in + --srcTarball) + if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then + SRC_TARBALL=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + exit 1 + fi + ;; + --outFolder) + if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then + OUT_FOLDER=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + exit 1 + fi + ;; + --pkgVersion) + if [ -n "$2" ] && [ ${2:0:1} != "-" ]; then + PKG_VERSION=$2 + shift 2 + else + echo "Error: Argument for $1 is missing" >&2 + exit 1 + fi + ;; + -*|--*=) # unsupported flags + echo "Error: Unsupported flag $1" >&2 + exit 1 + ;; + *) # preserve positional arguments + PARAMS="$PARAMS $1" + shift + ;; + esac +done + +echo "--srcTarball -> $SRC_TARBALL" +echo "--outFolder -> $OUT_FOLDER" +echo "--pkgVersion -> $PKG_VERSION" + +if [ -z "$PKG_VERSION" ]; then + echo "--pkgVersion parameter cannot be empty" + exit 1 +fi + +echo "-- create temp folder" +tmpdir=$(mktemp -d) +function cleanup { + echo "+++ cleanup -> remove $tmpdir" + rm -rf $tmpdir +} +trap cleanup EXIT + +pushd $tmpdir > /dev/null + +namever="node-v${PKG_VERSION}" + +if [[ -n $SRC_TARBALL ]]; then + upstream_tarball_name="$SRC_TARBALL" + clean_tarball_name="$OUT_FOLDER/$(basename $SRC_TARBALL)" +else + upstream_tarball_name="${namever}.tar.xz" + clean_tarball_name="$OUT_FOLDER/${namever}-clean.tar.xz" + download_url="https://nodejs.org/download/release/v${PKG_VERSION}/${upstream_tarball_name}" + + echo "Downloading upstream source tarball..." + curl -s -O $download_url +fi + +echo "Unpacking upstream source tarball..." +tar -xf $upstream_tarball_name + +echo "Removing bad vendored dependencies from source tree..." +rm -rf ./$namever/deps/openssl/openssl + +# Create a reproducible tarball +# Credit to https://reproducible-builds.org/docs/archives/ for instructions +# Do not update mtime value for new versions- keep the same value for ease of +# reproducing old tarball versions in the future if necessary +echo "Repacking source tarball..." +tar --sort=name --mtime="2021-11-10 00:00Z" \ + --owner=0 --group=0 --numeric-owner \ + --pax-option=exthdr.name=%d/PaxHeaders/%f,delete=atime,delete=ctime \ + -cJf $clean_tarball_name ./$namever + +popd > /dev/null +echo "Clean nodejs source tarball available at $clean_tarball_name" diff --git a/SPECS/nodejs24/nodejs24.signatures.json b/SPECS/nodejs24/nodejs24.signatures.json new file mode 100644 index 00000000000..5078533f52d --- /dev/null +++ b/SPECS/nodejs24/nodejs24.signatures.json @@ -0,0 +1,8 @@ +{ + "Signatures": { + "btest402.js": "fabaf4dacc13e93d54f825b87ffde18573214b149388a5f96176236dd31d7768", + "icu4c-77_1-data-bin-b.zip": "d8be12e03f782da350508b15354738ed97a3289008a787b6bd2a85434374bff4", + "icu4c-77_1-data-bin-l.zip": "0913674ff673c585f8bc08370916b6a6ccc30ffb6408a5c1bc3edbf5a687fd96", + "node-v24.12.0.tar.xz": "3541292851cb97d0e31b7b4943863c442f670a1af0534b3d8fa928aa1cc633b9" + } +} \ No newline at end of file diff --git a/SPECS/nodejs24/nodejs24.spec b/SPECS/nodejs24/nodejs24.spec new file mode 100644 index 00000000000..b53fb16952b --- /dev/null +++ b/SPECS/nodejs24/nodejs24.spec @@ -0,0 +1,327 @@ +# Retrieved from 'deps/npm/package.json' inside the sources tarball. +%define npm_version 11.6.2 + +%global nodejs_datadir %{_datarootdir}/nodejs + +# ICU - from tools/icu/current_ver.dep +%global icu_major 77 +%global icu_minor 1 +%global icu_version %{icu_major}.%{icu_minor} + +%global icudatadir %{nodejs_datadir}/icudata +%{!?little_endian: %global little_endian %(%{python3} -c "import sys;print (0 if sys.byteorder=='big' else 1)")} + +Summary: A JavaScript runtime built on Chrome's V8 JavaScript engine. +Name: nodejs24 +# WARNINGS: MUST check and update the 'npm_version' macro for every version update of this package. +# The version of NPM can be found inside the sources under 'deps/npm/package.json'. +Version: 24.12.0 +Release: 1%{?dist} +License: BSD AND MIT AND Public Domain AND NAIST-2003 AND Artistic-2.0 +Vendor: Microsoft Corporation +Distribution: Azure Linux +Group: Applications/System +URL: https://github.com/nodejs/node +# !!!! Nodejs code has a vendored version of OpenSSL code that must be removed from source tarball +# !!!! because it contains patented algorithms. +# !!! => use generate_source_tarball.sh script to create a clean and reproducible source tarball. +Source0: https://nodejs.org/download/release/v%{version}/node-v%{version}.tar.xz +Source1: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-b.zip +Source2: https://github.com/unicode-org/icu/releases/download/release-%{icu_major}-%{icu_minor}/icu4c-%{icu_major}_%{icu_minor}-data-bin-l.zip +Source3: btest402.js +Patch0: disable-tlsv1-tlsv1-1.patch +Patch1: CVE-2019-10906.patch +Patch2: CVE-2024-22195.patch +Patch3: CVE-2020-28493.patch +Patch4: CVE-2024-34064.patch +Patch5: CVE-2025-27516.patch +BuildRequires: brotli-devel +BuildRequires: c-ares-devel +BuildRequires: coreutils >= 8.22 +BuildRequires: gcc +BuildRequires: make +BuildRequires: ninja-build +BuildRequires: openssl-devel >= 1.1.1 +BuildRequires: python3 +BuildRequires: which +BuildRequires: zlib-devel +Requires: brotli +Requires: c-ares +Requires: coreutils >= 8.22 +Requires: openssl >= 1.1.1 +Provides: nodejs24 +# Until we make this as formal nodejs release, lets make it conflicting with nodejs20 +# This will uninstall nodejs20 during installation of nodejs24 +Conflicts: nodejs + +Recommends: nodejs-full-i18n = %{version}-%{release} +Provides: bundled(icu) = %{icu_version} + +%description +Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. +Node.js uses an event-driven, non-blocking I/O model that makes it lightweight and efficient. +The Node.js package ecosystem, npm, is the largest ecosystem of open source libraries in the world. + +%package devel +Summary: Development files node +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Requires: brotli-devel +Requires: openssl-devel >= 1.1.1 +Requires: zlib-devel + +%description devel +The nodejs-devel package contains libraries, header files and documentation +for developing applications that use nodejs. + +%package full-i18n +Summary: Non-English locale data for Node.js +Requires: %{name} = %{version}-%{release} + +%description full-i18n +Optional data files to provide full-icu support for Node.js. Remove this +package to save space if non-English locales are not needed. + +%package npm +Summary: Node.js Package Manager +Group: System Environment/Base +Requires: %{name} = %{version}-%{release} +Provides: npm = %{npm_version}.%{version}-%{release} + +%description npm +npm is a package manager for node.js. You can use it to install and publish +your node programs. It manages dependencies and does other cool stuff. + +%prep +%autosetup -p1 -n node-v%{version} + +%build +# remove unsupported TLSv1.3 cipher: +# Mariner's OpenSSL configuration does not allow for this TLSv1.3 +# cipher. OpenSSL does not like being asked to use TLSv1.3 ciphers +# it doesn't support (despite being fine processing similar cipher +# requests for TLS < 1.3). This cipher's presence in the default +# cipher list causes failures when initializing secure contexts +# in the context of Node's TLS library. +sed -i '/TLS_CHACHA20_POLY1305_SHA256/d' ./src/node_constants.h + +# remove brotli and zlib source code from deps folder +# keep the .gyp and .gypi files that are still used during configuration +find deps/zlib -name *.[ch] -delete +find deps/brotli -name *.[ch] -delete + +python3 configure.py \ + --prefix=%{_prefix} \ + --ninja \ + --shared-openssl \ + --shared-zlib \ + --shared-brotli \ + --with-intl=small-icu \ + --with-icu-source=deps/icu-small \ + --with-icu-default-data-dir=%{icudatadir} \ + --openssl-use-def-ca-store \ + --shared-cares + +JOBS=4 make %{?_smp_mflags} V=0 + +%install + +make %{?_smp_mflags} install DESTDIR=%{buildroot} +install -m 755 -d %{buildroot}%{_libdir}/node_modules/ +install -m 755 -d %{buildroot}%{_datadir}/%{name} + +# Remove junk files from node_modules/ - we should probably take care of +# this in the installer. +for FILE in .gitmodules .gitignore .npmignore .travis.yml \*.py[co]; do + find %{buildroot}%{_libdir}/node_modules/ -name "$FILE" -delete +done + +# Install the full-icu data files +mkdir -p %{buildroot}%{icudatadir} +%if 0%{?little_endian} +unzip -d %{buildroot}%{icudatadir} %{SOURCE2} icudt%{icu_major}l.dat +%else +unzip -d %{buildroot}%{icudatadir} %{SOURCE1} icudt%{icu_major}b.dat +%endif + +%check +# Make sure i18n support is working +NODE_PATH=%{buildroot}%{_prefix}/lib/node_modules:%{buildroot}%{_prefix}/lib/node_modules/npm/node_modules LD_LIBRARY_PATH=%{buildroot}%{_libdir} %{buildroot}/%{_bindir}/node --icu-data-dir=%{buildroot}%{icudatadir} %{SOURCE3} + +make cctest + +%post -p /sbin/ldconfig + +%files +%defattr(-,root,root) +%license LICENSE +%doc CHANGELOG.md README.md +%{_bindir}/node +%dir %{_prefix}/lib/node_modules +%{_mandir}/man*/* + +%files devel +%defattr(-,root,root) +%{_includedir}/* +%{_docdir}/* + +%files full-i18n +%dir %{icudatadir} +%{icudatadir}/icudt%{icu_major}*.dat + +%files npm +%defattr(-,root,root) +%{_bindir}/npm +%{_bindir}/npx +%{_bindir}/corepack +%{_prefix}/lib/node_modules/* + +%changelog +* Tue Dec 23 2025 Sandeep Karambelkar - 24.12.0-1 +- Upgrade to 24.12.0 +- Add support for passing runtime internationalization data + +* Fri Nov 07 2025 Azure Linux Security Servicing Account - 20.14.0-10 +- Patch for CVE-2025-5222 + +* Tue May 27 2025 Aninda Pradhan - 20.14.0-9 +- Patch CVE-2025-23165, CVE-2025-23166 + +* Wed May 21 2025 Aninda Pradhan - 20.14.0-8 +- Patch CVE-2025-47279 + +* Mon Mar 10 2025 Sandeep Karambelkar - 20.14.0-7 +- Patch CVE-2025-27516 + +* Wed Feb 12 2025 Kevin Lockwood - 20.14.0-6 +- Patch CVE-2020-28493 +- Patch CVE-2024-34064 + +* Tue Feb 11 2025 Kanishk Bansal - 20.14.0-5 +- Patch CVE-2025-22150, CVE-2025-23085, CVE-2024-22020, CVE-2024-22195 + +* Mon Jan 27 2025 Sumedh Sharma - 20.14.0-4 +- Patch CVE-2025-23083 + +* Tue Nov 19 2024 Bala - 20.14.0-3 +- Patch CVE-2024-21538 + +* Thu Sep 19 2024 Suresh Thelkar - 20.14.0-2 +- Patch CVE-2019-10906 + +* Fri Jun 07 2024 Nicolas Guibourge - 20.14.0-1 +- Upgrade to 20.14.0 to address CVEs + +* Thu Jun 06 2024 Riken Maharjan - 20.10.0-3 +- Separate npm from node using Fedora 50 (LICENSE: MIT) + +* Tue May 21 2024 Neha Agarwal - 20.10.0-2 +- Bump release to build with new libuv to fix CVE-2024-24806 + +* Wed Jan 31 2024 Saul Paredes - 20.10.0-1 +- Upgrade to nodejs to 20.10.0 and npm to 10.2.3 + +* Wed Sep 06 2023 Brian Fjeldstad - 16.20.2-2 +- Patch CVE-2023-35945 + +* Wed Sep 06 2023 Brian Fjeldstad - 16.20.2-1 +- Patch CVE-2023-32002 CVE-2023-32006 CVE-2023-32559 + +* Wed Jul 12 2023 Olivia Crain - 16.20.1-2 +- Backport upstream patches to fix CVE-2022-25883 + +* Wed Jun 28 2023 David Steele - 16.20.1-1 +- Upgrade to nodejs to 16.20.1 and npm to 8.19.4 + +* Tue May 30 2023 Dallas Delaney - 16.19.1-2 +- Fix CVE-2023-32067, CVE-2023-31130, CVE-2023-31147 by using system c-ares + +* Wed Mar 01 2023 CBL-Mariner Servicing Account - 16.19.1-1 +- Auto-upgrade to 16.19.1 - to fix CVE-2023-23936 +- Update npm version to 8.19.3 to reflect the actual version of npm bundled with v16.19.1 + +* Tue Dec 13 2022 Andrew Phelps - 16.18.1-2 +- Update license to reference Artistic 2.0 + +* Fri Dec 09 2022 CBL-Mariner Servicing Account - 16.18.1-1 +- Auto-upgrade to 16.18.1 - CVE-2022-43548 + +* Tue Oct 25 2022 Nicolas Guibourge - 16.17.1-2 +- Change npm_version to 8.15.0 to reflect the actual version of npm bundled with v16.17.1 + +* Mon Oct 24 2022 CBL-Mariner Servicing Account - 16.17.1-1 +- Upgrade to 16.17.1 + +* Thu Aug 18 2022 Cameron Baird - 16.16.0-2 +- Change npm_version to 8.11.0 to reflect the actual version of npm bundled with v16.16.0 + +* Tue Aug 02 2022 Cameron Baird - 16.16.0-1 +- Update to v16.16.0 (security update) to resolve CVE-2022-32213, CVE-2022-32214, CVE-2022-32215 + +* Mon May 16 2022 Mandeep Plaha - 16.14.2-2 +- Remove python3 as a runtime dependency as it is not needed during runtime. + +* Tue Apr 19 2022 Mandeep Plaha - 16.14.2-1 +- Update to 16.14.2. + +* Thu Feb 24 2022 Nicolas Guibourge - 16.14.0-1 +- Upgrade to 16.14.0. + +* Thu Nov 18 2021 Thomas Crain - 14.18.1-1 +- Update to version 14.18.1 to fix CVE-2021-22959, CVE-2021-22960, CVE-2021-37701, + CVE-2021-37712, CVE-2021-37713, CVE-2021-39134, CVE-2021-39135 +- Add patch to remove problematic cipher from default list +- Add config flag to use OpenSSL cert store instead of built-in Mozilla certs +- Add script to remove vendored OpenSSL tree from source tarball +- Update required OpenSSL version to 1.1.1 +- Use python configure script directly +- Lint spec + +* Thu Sep 23 2021 Pawel Winogrodzki - 14.17.2-2 +- Adding 'Provides' for 'npm'. + +* Mon Jul 19 2021 Neha Agarwal - 14.17.2-1 +- Update to version 14.17.2 to fix CVE-2021-22918 + +* Mon Jun 07 2021 Henry Beberman - 14.17.0-1 +- Update to nodejs version 14.17.0 + +* Sat May 09 2020 Nick Samson - 9.11.2-7 +- Added %%license line automatically + +* Mon May 04 2020 Paul Monson 9.11.2-6 +- Add patch that enables building openssl without TLS versions less 1.2 + +* Thu Apr 09 2020 Nicolas Ontiveros 9.11.2-5 +- Remove toybox and only use coreutils for requires. + +* Wed Apr 08 2020 Pawel Winogrodzki 9.11.2-4 +- License verified. +- Removed "%%define sha1". + +* Tue Sep 03 2019 Mateusz Malisz 9.11.2-3 +- Initial CBL-Mariner import from Photon (license: Apache2). + +* Tue Jan 08 2019 Alexey Makhalov 9.11.2-2 +- Added BuildRequires python2, which + +* Thu Sep 20 2018 Him Kalyan Bordoloi 9.11.2-1 +- Updated to version 9.11.2 + +* Mon Sep 10 2018 Him Kalyan Bordoloi 9.9.0-1 +- Updated to version 9.9.0 + +* Wed Feb 14 2018 Xiaolin Li 8.3.0-1 +- Updated to version 8.3.0 + +* Fri Oct 13 2017 Alexey Makhalov 7.7.4-4 +- Remove BuildArch + +* Mon Sep 18 2017 Alexey Makhalov 7.7.4-3 +- Requires coreutils or toybox + +* Fri Jul 14 2017 Chang Lee 7.7.4-2 +- Updated %check + +* Mon Mar 20 2017 Xiaolin Li 7.7.4-1 +- Initial packaging for Photon diff --git a/cgmanifest.json b/cgmanifest.json index ff22d47b2e3..73d9d181f9d 100644 --- a/cgmanifest.json +++ b/cgmanifest.json @@ -14462,6 +14462,16 @@ "type": "other", "other": { "name": "nodejs", + "version": "20.14.0", + "downloadUrl": "https://nodejs.org/download/release/v20.14.0/node-v20.14.0.tar.xz" + } + } + }, + { + "component": { + "type": "other", + "other": { + "name": "nodejs24", "version": "24.12.0", "downloadUrl": "https://nodejs.org/download/release/v24.12.0/node-v24.12.0.tar.xz" } From 6350c922e013f3f5ebf9c75e7d81f23dca152825 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Thu, 8 Jan 2026 06:52:12 +0000 Subject: [PATCH 10/11] use nodejs20 for nodejs default installations --- SPECS/nodejs/nodejs.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index 6b80ae56ff7..fcfc1c9dbaf 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -44,6 +44,7 @@ Requires: brotli Requires: c-ares Requires: coreutils >= 8.22 Requires: openssl >= 1.1.1 +Provides: nodejs %description Node.js is a JavaScript runtime built on Chrome's V8 JavaScript engine. From 38c8a93f6b60e10f12eac0efb0141f4d1b2daef6 Mon Sep 17 00:00:00 2001 From: Sandeep Karambelkar Date: Thu, 8 Jan 2026 08:29:30 +0000 Subject: [PATCH 11/11] Update license maps and bump nodejs release --- LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md | 2 +- LICENSES-AND-NOTICES/SPECS/data/licenses.json | 1 + SPECS/nodejs/nodejs.spec | 5 ++++- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md b/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md index 1a1f7ddbb35..a557f69af07 100644 --- a/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md +++ b/LICENSES-AND-NOTICES/SPECS/LICENSES-MAP.md @@ -17,7 +17,7 @@ The Azure Linux SPEC files originated from a variety of sources with varying lic | OpenEuler | [BSD-3 License](https://github.com/pytorch/pytorch/blob/master/LICENSE) | pytorch | | OpenMamba | [Openmamba GPLv2 License](https://www.gnu.org/licenses/old-licenses/gpl-2.0.txt) | bash-completion | | OpenSUSE | Following [openSUSE guidelines](https://en.opensuse.org/openSUSE:Specfile_guidelines#Specfile_Licensing) | ant
ant-junit
antlr
aopalliance
apache-commons-beanutils
apache-commons-cli
apache-commons-codec
apache-commons-collections
apache-commons-collections4
apache-commons-compress
apache-commons-daemon
apache-commons-dbcp
apache-commons-digester
apache-commons-httpclient
apache-commons-io
apache-commons-jexl
apache-commons-lang3
apache-commons-logging
apache-commons-net
apache-commons-pool
apache-commons-pool2
apache-commons-validator
apache-commons-vfs2
apache-parent
args4j
atinject
base64coder
bcel
bea-stax
beust-jcommander
bsf
byaccj
cal10n
cdparanoia
cglib
cni
containerized-data-importer
cpulimit
cri-o
ecj
ed25519-java
fillup
flux
gd
geronimo-specs
glassfish-annotation-api
gnu-getopt
gnu-regexp
golang-packaging
guava
hamcrest
hawtjni-runtime
httpcomponents-core
influx-cli
influxdb
jakarta-taglibs-standard
jansi
jarjar
java-cup
java-cup-bootstrap
javacc
javacc-bootstrap
javassist
jbcrypt
jboss-interceptors-1.2-api
jdepend
jflex
jflex-bootstrap
jlex
jline
jna
jsch
jsoup
jsr-305
jtidy
junit
junitperf
jzlib
kubevirt
kured
libcontainers-common
libtheora
libva
libvdpau
lynx
multus
objectweb-anttask
objectweb-asm
objenesis
oro
osgi-annotation
osgi-compendium
osgi-core
patterns-ceph-containers
plexus-classworlds
plexus-interpolation
plexus-utils
proj
psl-make-dafsa
publicsuffix
qdox
regexp
relaxngDatatype
rhino
ripgrep
servletapi4
servletapi5
shapelib
slf4j
trilead-ssh2
virtiofsd
xalan-j2
xbean
xcursor-themes
xerces-j2
xml-commons-apis
xml-commons-resolver
xmldb-api
xmlrpc-c
xmlunit
xz-java | -| Photon | [Photon License](LICENSE-PHOTON.md) and [Photon Notice](NOTICE.APACHE2).
Also see [LICENSE-EXCEPTIONS.PHOTON](LICENSE-EXCEPTIONS.PHOTON). | acl
alsa-lib
alsa-utils
ansible
apparmor
apr
apr-util
asciidoc
atftp
audit
autoconf
autoconf-archive
autofs
autogen
automake
babel
bash
bc
bcc
bind
binutils
bison
blktrace
boost
btrfs-progs
bubblewrap
build-essential
bzip2
c-ares
cairo
cassandra
cassandra-driver
cdrkit
check
chkconfig
chrpath
cifs-utils
clang
cloud-init
cloud-utils-growpart
cmake
cni-plugins
core-packages
coreutils
cpio
cppunit
cqlsh
cracklib
crash
crash-gcore-command
createrepo_c
cri-tools
cronie
curl
cyrus-sasl
cyrus-sasl-bootstrap
dbus
dbus-glib
dejagnu
device-mapper-multipath
dialog
diffutils
dkms
dmidecode
dnsmasq
docbook-dtd-xml
docbook-style-xsl
dosfstools
dracut
dstat
e2fsprogs
ed
efibootmgr
efivar
elfutils
emacs
erlang
etcd
ethtool
expat
expect
fcgi
file
filesystem
findutils
flex
fontconfig
fping
freetype
fuse
gawk
gc
gcc
gdb
gdbm
gettext
git
git-lfs
glib
glib-networking
glibc
glibmm
gmp
gnome-common
gnupg2
gnuplot
gnutls
gobject-introspection
golang
golang-1.23
golang-1.24
gperf
gperftools
gpgme
gptfdisk
grep
groff
grub2
gtest
gtk-doc
guile
gzip
haproxy
harfbuzz
haveged
hdparm
http-parser
httpd
i2c-tools
iana-etc
icu
initramfs
initscripts
inotify-tools
intltool
iotop
iperf3
iproute
ipset
iptables
iputils
ipvsadm
ipxe
irqbalance
itstool
jansson
jq
json-c
json-glib
kbd
keepalived
kernel
kernel-64k
kernel-headers
kernel-hwe
kernel-hwe-headers
kernel-ipe
kernel-lpg-innovate
kernel-mshv
kernel-rt
kernel-uvm
keyutils
kmod
krb5
less
libaio
libarchive
libassuan
libatomic_ops
libcap
libcap-ng
libconfig
libdb
libdnet
libedit
libestr
libevent
libfastjson
libffi
libgcrypt
libgpg-error
libgssglue
libgudev
libjpeg-turbo
libksba
liblogging
libmbim
libmnl
libmodulemd
libmpc
libmspack
libndp
libnetfilter_conntrack
libnetfilter_cthelper
libnetfilter_cttimeout
libnetfilter_queue
libnfnetlink
libnftnl
libnl3
libnsl2
libpcap
libpipeline
libpng
libpsl
libqmi
librelp
librepo
librsync
libseccomp
libselinux
libsepol
libserf
libsigc++30
libsolv
libsoup
libssh2
libtalloc
libtar
libtasn1
libtiff
libtirpc
libtool
libunistring
libunwind
libusb
libvirt
libwebp
libxml2
libxslt
libyaml
linux-firmware
lldb
lldpad
llvm
lm-sensors
lmdb
log4cpp
logrotate
lshw
lsof
lsscsi
ltrace
lttng-tools
lttng-ust
lvm2
lz4
lzo
m2crypto
m4
make
man-db
man-pages
maven
mc
mercurial
meson
mlocate
ModemManager
mpfr
msr-tools
mysql
nano
nasm
ncurses
ndctl
net-snmp
net-tools
nettle
newt
nfs-utils
nghttp2
nginx
ninja-build
nodejs
npth
nspr
nss
nss-altfiles
ntp
numactl
nvme-cli
oniguruma
OpenIPMI
openldap
openscap
openssh
openvswitch
ostree
pam
pango
parted
patch
pciutils
perl-Canary-Stability
perl-CGI
perl-common-sense
perl-Crypt-SSLeay
perl-DBD-SQLite
perl-DBI
perl-DBIx-Simple
perl-Exporter-Tiny
perl-File-HomeDir
perl-File-Which
perl-IO-Socket-SSL
perl-JSON-Any
perl-JSON-XS
perl-libintl-perl
perl-List-MoreUtils
perl-Module-Build
perl-Module-Install
perl-Module-ScanDeps
perl-Net-SSLeay
perl-NetAddr-IP
perl-Object-Accessor
perl-Path-Class
perl-Try-Tiny
perl-Types-Serialiser
perl-WWW-Curl
perl-XML-Parser
perl-YAML
perl-YAML-Tiny
pgbouncer
pinentry
polkit
popt
postgresql
procps-ng
protobuf
protobuf-c
psmisc
pth
pyasn1-modules
pyOpenSSL
pyparsing
pytest
python-appdirs
python-asn1crypto
python-atomicwrites
python-attrs
python-bcrypt
python-certifi
python-cffi
python-chardet
python-configobj
python-constantly
python-coverage
python-cryptography
python-daemon
python-dateutil
python-defusedxml
python-distro
python-docopt
python-docutils
python-ecdsa
python-geomet
python-gevent
python-hyperlink
python-hypothesis
python-idna
python-imagesize
python-incremental
python-iniparse
python-ipaddr
python-jinja2
python-jmespath
python-jsonpatch
python-jsonpointer
python-jsonschema
python-lockfile
python-lxml
python-mako
python-markupsafe
python-mistune
python-msgpack
python-netaddr
python-netifaces
python-ntplib
python-oauthlib
python-packaging
python-pam
python-pbr
python-ply
python-prettytable
python-psutil
python-psycopg2
python-py
python-pyasn1
python-pycodestyle
python-pycparser
python-pycurl
python-pygments
python-pynacl
python-requests
python-setuptools_scm
python-simplejson
python-six
python-snowballstemmer
python-sphinx-theme-alabaster
python-twisted
python-urllib3
python-vcversioner
python-virtualenv
python-wcwidth
python-webob
python-websocket-client
python-werkzeug
python-zope-event
python-zope-interface
python3
pytz
PyYAML
rapidjson
readline
rng-tools
rpcbind
rpcsvc-proto
rpm
rpm-ostree
rrdtool
rsync
rsyslog
ruby
rust
rust-1.75
scons
sed
sg3_utils
shadow-utils
slang
snappy
socat
sqlite
sshpass
strace
subversion
sudo
swig
syslinux
syslog-ng
sysstat
systemd-bootstrap
systemtap
tar
tboot
tcl
tcpdump
tcsh
tdnf
telegraf
texinfo
tmux
tpm2-abrmd
tpm2-pkcs11
tpm2-pytss
tpm2-tools
tpm2-tss
traceroute
tree
tzdata
unbound
unixODBC
unzip
usbutils
userspace-rcu
utf8proc
util-linux
valgrind
vim
vsftpd
WALinuxAgent
which
wpa_supplicant
xfsprogs
xinetd
xmlsec1
xmlto
xz
zchunk
zeromq
zip
zlib
zsh | +| Photon | [Photon License](LICENSE-PHOTON.md) and [Photon Notice](NOTICE.APACHE2).
Also see [LICENSE-EXCEPTIONS.PHOTON](LICENSE-EXCEPTIONS.PHOTON). | acl
alsa-lib
alsa-utils
ansible
apparmor
apr
apr-util
asciidoc
atftp
audit
autoconf
autoconf-archive
autofs
autogen
automake
babel
bash
bc
bcc
bind
binutils
bison
blktrace
boost
btrfs-progs
bubblewrap
build-essential
bzip2
c-ares
cairo
cassandra
cassandra-driver
cdrkit
check
chkconfig
chrpath
cifs-utils
clang
cloud-init
cloud-utils-growpart
cmake
cni-plugins
core-packages
coreutils
cpio
cppunit
cqlsh
cracklib
crash
crash-gcore-command
createrepo_c
cri-tools
cronie
curl
cyrus-sasl
cyrus-sasl-bootstrap
dbus
dbus-glib
dejagnu
device-mapper-multipath
dialog
diffutils
dkms
dmidecode
dnsmasq
docbook-dtd-xml
docbook-style-xsl
dosfstools
dracut
dstat
e2fsprogs
ed
efibootmgr
efivar
elfutils
emacs
erlang
etcd
ethtool
expat
expect
fcgi
file
filesystem
findutils
flex
fontconfig
fping
freetype
fuse
gawk
gc
gcc
gdb
gdbm
gettext
git
git-lfs
glib
glib-networking
glibc
glibmm
gmp
gnome-common
gnupg2
gnuplot
gnutls
gobject-introspection
golang
golang-1.23
golang-1.24
gperf
gperftools
gpgme
gptfdisk
grep
groff
grub2
gtest
gtk-doc
guile
gzip
haproxy
harfbuzz
haveged
hdparm
http-parser
httpd
i2c-tools
iana-etc
icu
initramfs
initscripts
inotify-tools
intltool
iotop
iperf3
iproute
ipset
iptables
iputils
ipvsadm
ipxe
irqbalance
itstool
jansson
jq
json-c
json-glib
kbd
keepalived
kernel
kernel-64k
kernel-headers
kernel-hwe
kernel-hwe-headers
kernel-ipe
kernel-lpg-innovate
kernel-mshv
kernel-rt
kernel-uvm
keyutils
kmod
krb5
less
libaio
libarchive
libassuan
libatomic_ops
libcap
libcap-ng
libconfig
libdb
libdnet
libedit
libestr
libevent
libfastjson
libffi
libgcrypt
libgpg-error
libgssglue
libgudev
libjpeg-turbo
libksba
liblogging
libmbim
libmnl
libmodulemd
libmpc
libmspack
libndp
libnetfilter_conntrack
libnetfilter_cthelper
libnetfilter_cttimeout
libnetfilter_queue
libnfnetlink
libnftnl
libnl3
libnsl2
libpcap
libpipeline
libpng
libpsl
libqmi
librelp
librepo
librsync
libseccomp
libselinux
libsepol
libserf
libsigc++30
libsolv
libsoup
libssh2
libtalloc
libtar
libtasn1
libtiff
libtirpc
libtool
libunistring
libunwind
libusb
libvirt
libwebp
libxml2
libxslt
libyaml
linux-firmware
lldb
lldpad
llvm
lm-sensors
lmdb
log4cpp
logrotate
lshw
lsof
lsscsi
ltrace
lttng-tools
lttng-ust
lvm2
lz4
lzo
m2crypto
m4
make
man-db
man-pages
maven
mc
mercurial
meson
mlocate
ModemManager
mpfr
msr-tools
mysql
nano
nasm
ncurses
ndctl
net-snmp
net-tools
nettle
newt
nfs-utils
nghttp2
nginx
ninja-build
nodejs
nodejs24
npth
nspr
nss
nss-altfiles
ntp
numactl
nvme-cli
oniguruma
OpenIPMI
openldap
openscap
openssh
openvswitch
ostree
pam
pango
parted
patch
pciutils
perl-Canary-Stability
perl-CGI
perl-common-sense
perl-Crypt-SSLeay
perl-DBD-SQLite
perl-DBI
perl-DBIx-Simple
perl-Exporter-Tiny
perl-File-HomeDir
perl-File-Which
perl-IO-Socket-SSL
perl-JSON-Any
perl-JSON-XS
perl-libintl-perl
perl-List-MoreUtils
perl-Module-Build
perl-Module-Install
perl-Module-ScanDeps
perl-Net-SSLeay
perl-NetAddr-IP
perl-Object-Accessor
perl-Path-Class
perl-Try-Tiny
perl-Types-Serialiser
perl-WWW-Curl
perl-XML-Parser
perl-YAML
perl-YAML-Tiny
pgbouncer
pinentry
polkit
popt
postgresql
procps-ng
protobuf
protobuf-c
psmisc
pth
pyasn1-modules
pyOpenSSL
pyparsing
pytest
python-appdirs
python-asn1crypto
python-atomicwrites
python-attrs
python-bcrypt
python-certifi
python-cffi
python-chardet
python-configobj
python-constantly
python-coverage
python-cryptography
python-daemon
python-dateutil
python-defusedxml
python-distro
python-docopt
python-docutils
python-ecdsa
python-geomet
python-gevent
python-hyperlink
python-hypothesis
python-idna
python-imagesize
python-incremental
python-iniparse
python-ipaddr
python-jinja2
python-jmespath
python-jsonpatch
python-jsonpointer
python-jsonschema
python-lockfile
python-lxml
python-mako
python-markupsafe
python-mistune
python-msgpack
python-netaddr
python-netifaces
python-ntplib
python-oauthlib
python-packaging
python-pam
python-pbr
python-ply
python-prettytable
python-psutil
python-psycopg2
python-py
python-pyasn1
python-pycodestyle
python-pycparser
python-pycurl
python-pygments
python-pynacl
python-requests
python-setuptools_scm
python-simplejson
python-six
python-snowballstemmer
python-sphinx-theme-alabaster
python-twisted
python-urllib3
python-vcversioner
python-virtualenv
python-wcwidth
python-webob
python-websocket-client
python-werkzeug
python-zope-event
python-zope-interface
python3
pytz
PyYAML
rapidjson
readline
rng-tools
rpcbind
rpcsvc-proto
rpm
rpm-ostree
rrdtool
rsync
rsyslog
ruby
rust
rust-1.75
scons
sed
sg3_utils
shadow-utils
slang
snappy
socat
sqlite
sshpass
strace
subversion
sudo
swig
syslinux
syslog-ng
sysstat
systemd-bootstrap
systemtap
tar
tboot
tcl
tcpdump
tcsh
tdnf
telegraf
texinfo
tmux
tpm2-abrmd
tpm2-pkcs11
tpm2-pytss
tpm2-tools
tpm2-tss
traceroute
tree
tzdata
unbound
unixODBC
unzip
usbutils
userspace-rcu
utf8proc
util-linux
valgrind
vim
vsftpd
WALinuxAgent
which
wpa_supplicant
xfsprogs
xinetd
xmlsec1
xmlto
xz
zchunk
zeromq
zip
zlib
zsh | | RPM software management source | [GPLv2+ License](https://github.com/rpm-software-management/dnf5/blob/main/COPYING.md) | dnf5 | | Source project | Same as the source project. | python-nocaselist | | Sysbench source | [GPLv2+ License](https://github.com/akopytov/sysbench/blob/master/COPYING) | sysbench | diff --git a/LICENSES-AND-NOTICES/SPECS/data/licenses.json b/LICENSES-AND-NOTICES/SPECS/data/licenses.json index 5d8538ae5b0..2f6ef2ad9f2 100644 --- a/LICENSES-AND-NOTICES/SPECS/data/licenses.json +++ b/LICENSES-AND-NOTICES/SPECS/data/licenses.json @@ -2947,6 +2947,7 @@ "nginx", "ninja-build", "nodejs", + "nodejs24", "npth", "nspr", "nss", diff --git a/SPECS/nodejs/nodejs.spec b/SPECS/nodejs/nodejs.spec index fcfc1c9dbaf..07262b4c0d0 100644 --- a/SPECS/nodejs/nodejs.spec +++ b/SPECS/nodejs/nodejs.spec @@ -5,7 +5,7 @@ Name: nodejs # WARNINGS: MUST check and update the 'npm_version' macro for every version update of this package. # The version of NPM can be found inside the sources under 'deps/npm/package.json'. Version: 20.14.0 -Release: 10%{?dist} +Release: 11%{?dist} License: BSD AND MIT AND Public Domain AND NAIST-2003 AND Artistic-2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -142,6 +142,9 @@ make cctest %{_prefix}/lib/node_modules/* %changelog +* Thr Jan 08 2025 Sandeep Karambelkar - 20.14.0-11 +- Add nodejs provides to manage co existence with nodejs24 + * Fri Nov 07 2025 Azure Linux Security Servicing Account - 20.14.0-10 - Patch for CVE-2025-5222