upgpkg(main/nodejs-lts): update to v16.17.1

This commit is contained in:
termux-pacman-bot
2022-10-07 01:00:11 +00:00
parent f322033770
commit 3a6cb39ddd
14 changed files with 192 additions and 324 deletions

View File

@@ -2,10 +2,9 @@ TERMUX_PKG_HOMEPAGE=https://nodejs.org/
TERMUX_PKG_DESCRIPTION="Open Source, cross-platform JavaScript runtime environment"
TERMUX_PKG_LICENSE="MIT"
TERMUX_PKG_MAINTAINER="Yaksh Bariya <yakshbari4@gmail.com>"
TERMUX_PKG_VERSION=16.16.0
TERMUX_PKG_REVISION=2
TERMUX_PKG_VERSION=16.17.1
TERMUX_PKG_SRCURL=https://nodejs.org/dist/v${TERMUX_PKG_VERSION}/node-v${TERMUX_PKG_VERSION}.tar.xz
TERMUX_PKG_SHA256=145151eff3b2aa5ebe73384009c52271a83740ae687a93c98c628cd7d52736eb
TERMUX_PKG_SHA256=6721feb4152d56d2c6b358ce397abd5a7f1daf09ee2e25c5021b9b4d3f86a330
# Note that we do not use a shared libuv to avoid an issue with the Android
# linker, which does not use symbols of linked shared libraries when resolving
# symbols on dlopen(). See https://github.com/termux/termux-packages/issues/462.

View File

@@ -1,321 +0,0 @@
From a54283a638703fdc66163720806a26a9801bbf92 Mon Sep 17 00:00:00 2001
From: Ben Noordhuis <info@bnoordhuis.nl>
Date: Sun, 11 Sep 2022 10:48:34 +0200
Subject: [PATCH] crypto: fix weak randomness in WebCrypto keygen
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Commit dae283d96f from August 2020 introduced a call to EntropySource()
in SecretKeyGenTraits::DoKeyGen() in src/crypto/crypto_keygen.cc. There
are two problems with that:
1. It does not check the return value, it assumes EntropySource() always
succeeds, but it can (and sometimes will) fail.
2. The random data returned byEntropySource() may not be
cryptographically strong and therefore not suitable as keying
material.
An example is a freshly booted system or a system without /dev/random or
getrandom(2).
EntropySource() calls out to openssl's RAND_poll() and RAND_bytes() in a
best-effort attempt to obtain random data. OpenSSL has a built-in CSPRNG
but that can fail to initialize, in which case it's possible either:
1. No random data gets written to the output buffer, i.e., the output is
unmodified, or
2. Weak random data is written. It's theoretically possible for the
output to be fully predictable because the CSPRNG starts from a
predictable state.
Replace EntropySource() and CheckEntropy() with new function CSPRNG()
that enforces checking of the return value. Abort on startup when the
entropy pool fails to initialize because that makes it too easy to
compromise the security of the process.
Refs: https://hackerone.com/bugs?report_id=1690000
Refs: https://github.com/nodejs/node/pull/35093
Backport-PR-URL: https://github.com/nodejs-private/node-private/pull/349
PR-URL: https://github.com/nodejs-private/node-private/pull/346
Reviewed-By: Vladimir de Turckheim <vlad2t@hotmail.com>
Reviewed-By: Tobias Nießen <tniessen@tnie.de>
CVE-ID: CVE-2022-35255
---
node.gyp | 2 ++
src/crypto/crypto_context.cc | 19 ++++++++++--------
src/crypto/crypto_keygen.cc | 8 +++++++-
src/crypto/crypto_keygen.h | 3 ---
src/crypto/crypto_random.cc | 15 +++++++--------
src/crypto/crypto_util.cc | 28 ++++++++-------------------
src/crypto/crypto_util.h | 37 ++++++++++++------------------------
src/inspector_io.cc | 3 +--
src/node.cc | 24 +++++++++++++++--------
9 files changed, 64 insertions(+), 75 deletions(-)
diff --git a/node.gyp b/node.gyp
index 65cc076be6a1..97cdbb531da9 100644
--- a/node.gyp
+++ b/node.gyp
@@ -627,6 +627,8 @@
'openssl_default_cipher_list%': '',
},
+ 'cflags': ['-Werror=unused-result'],
+
'defines': [
'NODE_ARCH="<(target_arch)"',
'NODE_PLATFORM="<(OS)"',
diff --git a/src/crypto/crypto_context.cc b/src/crypto/crypto_context.cc
index e2291f72b662..0bb5bedbcd1d 100644
--- a/src/crypto/crypto_context.cc
+++ b/src/crypto/crypto_context.cc
@@ -541,9 +541,9 @@ void SecureContext::Init(const FunctionCallbackInfo<Value>& args) {
// OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
// exposed in the public API. To retain compatibility, install a callback
// which restores the old algorithm.
- if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
- RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
- RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
+ if (CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)).is_err() ||
+ CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)).is_err() ||
+ CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)).is_err()) {
return THROW_ERR_CRYPTO_OPERATION_FAILED(
env, "Error generating ticket keys");
}
@@ -1244,11 +1244,14 @@ int SecureContext::TicketCompatibilityCallback(SSL* ssl,
if (enc) {
memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
- if (RAND_bytes(iv, 16) <= 0 ||
- EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
- sc->ticket_key_aes_, iv) <= 0 ||
- HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
- EVP_sha256(), nullptr) <= 0) {
+ if (CSPRNG(iv, 16).is_err() ||
+ EVP_EncryptInit_ex(
+ ectx, EVP_aes_128_cbc(), nullptr, sc->ticket_key_aes_, iv) <= 0 ||
+ HMAC_Init_ex(hctx,
+ sc->ticket_key_hmac_,
+ sizeof(sc->ticket_key_hmac_),
+ EVP_sha256(),
+ nullptr) <= 0) {
return -1;
}
return 1;
diff --git a/src/crypto/crypto_keygen.cc b/src/crypto/crypto_keygen.cc
index e4e9c2274583..0bc0c3a2ac58 100644
--- a/src/crypto/crypto_keygen.cc
+++ b/src/crypto/crypto_keygen.cc
@@ -84,7 +84,13 @@ KeyGenJobStatus SecretKeyGenTraits::DoKeyGen(
SecretKeyGenConfig* params) {
CHECK_LE(params->length, INT_MAX);
params->out = MallocOpenSSL<char>(params->length);
- EntropySource(reinterpret_cast<unsigned char*>(params->out), params->length);
+ if (CSPRNG(reinterpret_cast<unsigned char*>(params->out),
+ params->length).is_err()) {
+ OPENSSL_clear_free(params->out, params->length);
+ params->out = nullptr;
+ params->length = 0;
+ return KeyGenJobStatus::FAILED;
+ }
return KeyGenJobStatus::OK;
}
diff --git a/src/crypto/crypto_keygen.h b/src/crypto/crypto_keygen.h
index 01407de83c7b..171977960f66 100644
--- a/src/crypto/crypto_keygen.h
+++ b/src/crypto/crypto_keygen.h
@@ -75,9 +75,6 @@ class KeyGenJob final : public CryptoJob<KeyGenTraits> {
std::move(params)) {}
void DoThreadPoolWork() override {
- // Make sure the CSPRNG is properly seeded so the results are secure.
- CheckEntropy();
-
AdditionalParams* params = CryptoJob<KeyGenTraits>::params();
switch (KeyGenTraits::DoKeyGen(AsyncWrap::env(), params)) {
diff --git a/src/crypto/crypto_random.cc b/src/crypto/crypto_random.cc
index 648fda211c43..1459e410453d 100644
--- a/src/crypto/crypto_random.cc
+++ b/src/crypto/crypto_random.cc
@@ -66,8 +66,7 @@ bool RandomBytesTraits::DeriveBits(
Environment* env,
const RandomBytesConfig& params,
ByteSource* unused) {
- CheckEntropy(); // Ensure that OpenSSL's PRNG is properly seeded.
- return RAND_bytes(params.buffer, params.size) != 0;
+ return CSPRNG(params.buffer, params.size).is_ok();
}
void RandomPrimeConfig::MemoryInfo(MemoryTracker* tracker) const {
@@ -156,12 +155,12 @@ Maybe<bool> RandomPrimeTraits::AdditionalConfig(
return Just(true);
}
-bool RandomPrimeTraits::DeriveBits(
- Environment* env,
- const RandomPrimeConfig& params,
- ByteSource* unused) {
-
- CheckEntropy();
+bool RandomPrimeTraits::DeriveBits(Environment* env,
+ const RandomPrimeConfig& params,
+ ByteSource* unused) {
+ // BN_generate_prime_ex() calls RAND_bytes_ex() internally.
+ // Make sure the CSPRNG is properly seeded.
+ CHECK(CSPRNG(nullptr, 0).is_ok());
if (BN_generate_prime_ex(
params.prime.get(),
diff --git a/src/crypto/crypto_util.cc b/src/crypto/crypto_util.cc
index 58a5d88d7a10..652f6e0b12e2 100644
--- a/src/crypto/crypto_util.cc
+++ b/src/crypto/crypto_util.cc
@@ -60,26 +60,14 @@ int VerifyCallback(int preverify_ok, X509_STORE_CTX* ctx) {
return 1;
}
-void CheckEntropy() {
- for (;;) {
- int status = RAND_status();
- CHECK_GE(status, 0); // Cannot fail.
- if (status != 0)
- break;
-
- // Give up, RAND_poll() not supported.
- if (RAND_poll() == 0)
- break;
- }
-}
-
-bool EntropySource(unsigned char* buffer, size_t length) {
- // Ensure that OpenSSL's PRNG is properly seeded.
- CheckEntropy();
- // RAND_bytes() can return 0 to indicate that the entropy data is not truly
- // random. That's okay, it's still better than V8's stock source of entropy,
- // which is /dev/urandom on UNIX platforms and the current time on Windows.
- return RAND_bytes(buffer, length) != -1;
+MUST_USE_RESULT CSPRNGResult CSPRNG(void* buffer, size_t length) {
+ do {
+ if (1 == RAND_status())
+ if (1 == RAND_bytes(static_cast<unsigned char*>(buffer), length))
+ return {true};
+ } while (1 == RAND_poll());
+
+ return {false};
}
int PasswordCallback(char* buf, int size, int rwflag, void* u) {
diff --git a/src/crypto/crypto_util.h b/src/crypto/crypto_util.h
index 07ea8e44da3e..f26422ee106a 100644
--- a/src/crypto/crypto_util.h
+++ b/src/crypto/crypto_util.h
@@ -110,31 +110,18 @@ struct MarkPopErrorOnReturn {
~MarkPopErrorOnReturn() { ERR_pop_to_mark(); }
};
-// Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
-// The entropy pool starts out empty and needs to fill up before the PRNG
-// can be used securely. Once the pool is filled, it never dries up again;
-// its contents is stirred and reused when necessary.
-//
-// OpenSSL normally fills the pool automatically but not when someone starts
-// generating random numbers before the pool is full: in that case OpenSSL
-// keeps lowering the entropy estimate to thwart attackers trying to guess
-// the initial state of the PRNG.
-//
-// When that happens, we will have to wait until enough entropy is available.
-// That should normally never take longer than a few milliseconds.
-//
-// OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
-// block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
-// block under normal circumstances.
-//
-// The only time when /dev/urandom may conceivably block is right after boot,
-// when the whole system is still low on entropy. That's not something we can
-// do anything about.
-void CheckEntropy();
-
-// Generate length bytes of random data. If this returns false, the data
-// may not be truly random but it's still generally good enough.
-bool EntropySource(unsigned char* buffer, size_t length);
+struct CSPRNGResult {
+ const bool ok;
+ MUST_USE_RESULT bool is_ok() const { return ok; }
+ MUST_USE_RESULT bool is_err() const { return !ok; }
+};
+
+// Either succeeds with exactly |length| bytes of cryptographically
+// strong pseudo-random data, or fails. This function may block.
+// Don't assume anything about the contents of |buffer| on error.
+// As a special case, |length == 0| can be used to check if the CSPRNG
+// is properly seeded without consuming entropy.
+MUST_USE_RESULT CSPRNGResult CSPRNG(void* buffer, size_t length);
int PasswordCallback(char* buf, int size, int rwflag, void* u);
diff --git a/src/inspector_io.cc b/src/inspector_io.cc
index 7f52fc605933..7e0b3ea63cff 100644
--- a/src/inspector_io.cc
+++ b/src/inspector_io.cc
@@ -46,8 +46,7 @@ std::string ScriptPath(uv_loop_t* loop, const std::string& script_name) {
// Used ver 4 - with numbers
std::string GenerateID() {
uint16_t buffer[8];
- CHECK(crypto::EntropySource(reinterpret_cast<unsigned char*>(buffer),
- sizeof(buffer)));
+ CHECK(crypto::CSPRNG(buffer, sizeof(buffer)).is_ok());
char uuid[256];
snprintf(uuid, sizeof(uuid), "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
diff --git a/src/node.cc b/src/node.cc
index 5ac6ca75389d..69e817c80310 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -1092,11 +1092,10 @@ InitializationResult InitializeOncePerProcess(
// fipsinstall command. If the path to this file is incorrect no error
// will be reported.
//
- // For Node.js this will mean that EntropySource will be called by V8 as
- // part of its initialization process, and EntropySource will in turn call
- // CheckEntropy. CheckEntropy will call RAND_status which will now always
- // return 0, leading to an endless loop and the node process will appear to
- // hang/freeze.
+ // For Node.js this will mean that CSPRNG() will be called by V8 as
+ // part of its initialization process, and CSPRNG() will in turn call
+ // call RAND_status which will now always return 0, leading to an endless
+ // loop and the node process will appear to hang/freeze.
// Passing NULL as the config file will allow the default openssl.cnf file
// to be loaded, but the default section in that file will not be used,
@@ -1156,14 +1155,23 @@ InitializationResult InitializeOncePerProcess(
}
#endif
- // V8 on Windows doesn't have a good source of entropy. Seed it from
- // OpenSSL's pool.
- V8::SetEntropySource(crypto::EntropySource);
if (!crypto::ProcessFipsOptions()) {
return handle_openssl_error(ERR_GET_REASON(ERR_peek_error()),
fips_error_msg,
&result);
}
+
+ // Ensure CSPRNG is properly seeded.
+ CHECK(crypto::CSPRNG(nullptr, 0).is_ok());
+
+ V8::SetEntropySource([](unsigned char* buffer, size_t length) {
+ // V8 falls back to very weak entropy when this function fails
+ // and /dev/urandom isn't available. That wouldn't be so bad if
+ // the entropy was only used for Math.random() but it's also used for
+ // hash table and address space layout randomization. Better to abort.
+ CHECK(crypto::CSPRNG(buffer, length).is_ok());
+ return true;
+ });
#endif // HAVE_OPENSSL && !defined(OPENSSL_IS_BORINGSSL)
}
per_process::v8_platform.Initialize(

View File

@@ -0,0 +1,12 @@
--- ./src/node_report.cc 2022-09-23 08:19:19.000000000 +0530
+++ ./src/node_report.cc.mod 2022-10-06 21:25:11.127454780 +0530
@@ -425,6 +425,9 @@
}
writer->json_arrayend();
uv_free_cpu_info(cpu_info, count);
+ } else {
+ writer->json_arraystart("cpus");
+ writer->json_arrayend();
}
}

View File

@@ -0,0 +1,17 @@
--- ./test/parallel/test-blob-buffer-too-large.js.orig 2022-06-05 08:43:15.647600971 +0530
+++ ./test/parallel/test-blob-buffer-too-large.js 2022-06-05 08:55:58.717600680 +0530
@@ -4,10 +4,14 @@
const common = require('../common');
const assert = require('assert');
const { Blob } = require('buffer');
+const { platform } = require('os');
if (common.isFreeBSD)
common.skip('Oversized buffer make the FreeBSD CI runner crash');
+if (platform() === 'android')
+ common.skip('Android will kill heavy memory using processes sometimes crashing Termux');
+
try {
new Blob([new Uint8Array(0xffffffff), [1]]);
} catch (e) {

View File

@@ -0,0 +1,11 @@
--- ./test/parallel/test-child-process-exec-env.js.orig 2022-06-05 08:57:52.717600637 +0530
+++ ./test/parallel/test-child-process-exec-env.js 2022-06-05 09:02:24.887600533 +0530
@@ -44,7 +44,7 @@
}
if (!isWindows) {
- child = exec('/usr/bin/env', { env: { 'HELLO': 'WORLD' } }, after);
+ child = exec('@TERMUX_PREFIX@/bin/env', { env: { 'HELLO': 'WORLD' } }, after);
} else {
child = exec('set',
{ env: { ...process.env, 'HELLO': 'WORLD' } },

View File

@@ -0,0 +1,11 @@
--- ./test/parallel/test-child-process-spawnsync-shell.js.orig 2022-06-05 08:34:30.587601172 +0530
+++ ./test/parallel/test-child-process-spawnsync-shell.js 2022-06-05 08:34:48.497601165 +0530
@@ -82,7 +82,7 @@
test('darwin', '/bin/csh', '/bin/csh');
// Test Android platforms.
- test('android', true, '/system/bin/sh');
+ test('android', true, '@TERMUX_PREFIX@/bin/sh');
// Test Windows platforms with a user specified shell.
test('win32', 'powershell.exe', 'powershell.exe');

View File

@@ -0,0 +1,17 @@
--- ./test/parallel/test-child-process-stdio-overlapped.js.orig 2022-06-05 09:57:50.337599264 +0530
+++ ./test/parallel/test-child-process-stdio-overlapped.js 2022-06-05 10:12:13.197598935 +0530
@@ -28,10 +28,13 @@
const assert = require('assert');
const path = require('path');
const child_process = require('child_process');
+const { mkdtempSync } = require('fs')
const exeExtension = process.platform === 'win32' ? '.exe' : '';
const exe = 'overlapped-checker' + exeExtension;
-const exePath = path.join(path.dirname(process.execPath), exe);
+const exePath = path.join(mkdtempSync(process.env.TMPDIR + '/' || '@TERMUX_PREFIX@/tmp/'), exe);
+
+child_process.spawnSync('clang', ['-O3', 'test/overlapped-checker/main_unix.c', '-o', exePath]);
const child = child_process.spawn(exePath, [], {
stdio: ['overlapped', 'pipe', 'pipe']

View File

@@ -0,0 +1,19 @@
--- ./test/parallel/test-dgram-bind-fd.js.orig 2022-06-05 10:30:47.907598510 +0530
+++ ./test/parallel/test-dgram-bind-fd.js 2022-06-05 10:31:18.697598498 +0530
@@ -7,6 +7,7 @@
const assert = require('assert');
const dgram = require('dgram');
const { internalBinding } = require('internal/test/binding');
+const { platform } = require('os');
const { UDP } = internalBinding('udp_wrap');
const { UV_UDP_REUSEADDR } = require('os').constants;
@@ -77,7 +78,7 @@
const sendBufferSize = socket.getSendBufferSize();
// note: linux will double the buffer size
- const expectedBufferSize = common.isLinux ?
+ const expectedBufferSize = (common.isLinux || platform() === 'android') ?
BUFFER_SIZE * 2 : BUFFER_SIZE;
assert.strictEqual(recvBufferSize, expectedBufferSize);
assert.strictEqual(sendBufferSize, expectedBufferSize);

View File

@@ -0,0 +1,40 @@
--- ./test/parallel/test-dgram-membership.js.orig 2022-06-05 10:44:44.687598191 +0530
+++ ./test/parallel/test-dgram-membership.js 2022-06-05 10:46:16.867598156 +0530
@@ -3,6 +3,7 @@
const common = require('../common');
const assert = require('assert');
const dgram = require('dgram');
+const { platform } = require('os');
const multicastAddress = '224.0.0.114';
const setup = dgram.createSocket.bind(dgram, { type: 'udp4', reuseAddr: true });
@@ -106,11 +107,12 @@
// addSourceSpecificMembership with invalid groupAddress should throw
{
const socket = setup();
+ const errCode = platform() === 'android' ? 'ENOSYS' : 'EINVAL';
assert.throws(() => {
socket.addSourceSpecificMembership(multicastAddress, '0');
}, {
- code: 'EINVAL',
- message: 'addSourceSpecificMembership EINVAL'
+ code: errCode,
+ message: `addSourceSpecificMembership ${errCode}`
});
socket.close();
}
@@ -144,11 +146,12 @@
// dropSourceSpecificMembership with invalid UDP should throw
{
const socket = setup();
+ const errCode = platform() === 'android' ? 'ENOSYS' : 'EINVAL';
assert.throws(() => {
socket.dropSourceSpecificMembership(multicastAddress, '0');
}, {
- code: 'EINVAL',
- message: 'dropSourceSpecificMembership EINVAL'
+ code: errCode,
+ message: `dropSourceSpecificMembership ${errCode}`
});
socket.close();
}

View File

@@ -0,0 +1,19 @@
--- ./test/parallel/test-dgram-socket-buffer-size.js.orig 2022-06-05 10:48:41.037598101 +0530
+++ ./test/parallel/test-dgram-socket-buffer-size.js 2022-06-05 10:48:52.537598096 +0530
@@ -6,6 +6,7 @@
const dgram = require('dgram');
const { inspect } = require('util');
const { internalBinding } = require('internal/test/binding');
+const { platform } = require('os');
const {
UV_EBADF,
UV_EINVAL,
@@ -115,7 +116,7 @@
socket.setSendBufferSize(10000);
// note: linux will double the buffer size
- const expectedBufferSize = common.isLinux ? 20000 : 10000;
+ const expectedBufferSize = (common.isLinux || platform() === 'android') ? 20000 : 10000;
assert.strictEqual(socket.getRecvBufferSize(), expectedBufferSize);
assert.strictEqual(socket.getSendBufferSize(), expectedBufferSize);
socket.close();

View File

@@ -0,0 +1,11 @@
--- ./test/parallel/test-gc-http-client-connaborted.js.orig 2022-06-05 08:39:51.327601049 +0530
+++ ./test/parallel/test-gc-http-client-connaborted.js 2022-06-05 08:40:14.897601040 +0530
@@ -8,7 +8,7 @@
const http = require('http');
const os = require('os');
-const cpus = os.cpus().length;
+const cpus = 8;
let createClients = true;
let done = 0;
let count = 0;

View File

@@ -0,0 +1,11 @@
--- ./test/parallel/test-process-constants-noatime.js.orig 2022-06-21 15:34:16.647265960 +0530
+++ ./test/parallel/test-process-constants-noatime.js 2022-06-21 15:34:38.957265951 +0530
@@ -4,7 +4,7 @@
const assert = require('assert');
const constants = require('fs').constants;
-if (common.isLinux) {
+if (common.isLinux || process.platform === 'android') {
assert('O_NOATIME' in constants);
assert.strictEqual(constants.O_NOATIME, 0x40000);
} else {

View File

@@ -0,0 +1,11 @@
--- ./test/sequential/test-gc-http-client-onerror.js.orig 2022-06-05 10:18:02.427598802 +0530
+++ ./test/sequential/test-gc-http-client-onerror.js 2022-06-05 10:18:17.627598796 +0530
@@ -6,7 +6,7 @@
const common = require('../common');
const onGC = require('../common/ongc');
-const cpus = require('os').cpus().length;
+const cpus = 8;
function serverHandler(req, res) {
req.resume();

View File

@@ -0,0 +1,11 @@
--- ./test/sequential/test-gc-http-client.js.orig 2022-06-05 10:17:44.127598809 +0530
+++ ./test/sequential/test-gc-http-client.js 2022-06-05 10:17:53.947598805 +0530
@@ -5,7 +5,7 @@
const common = require('../common');
const onGC = require('../common/ongc');
-const cpus = require('os').cpus().length;
+const cpus = 8;
function serverHandler(req, res) {
res.writeHead(200, { 'Content-Type': 'text/plain' });