summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPoonam Jadhav <Poonam.Jadhav@kpit.com>2023-03-03 18:02:13 +0530
committerArmin Kuster <akuster808@gmail.com>2023-03-18 16:16:42 -0400
commitb691797f7768378a8caf36812312848add77377a (patch)
treeefbd0abd66be10619d87f4514795f94a9fef5c1e
parentdf7fba37446e8af5f043b7d4ba0e2611578a016f (diff)
downloadmeta-openembedded-b691797f7768378a8caf36812312848add77377a.tar.gz
nodejs: Fix CVE-2022-35255
Add patch to fix CVE-2022-35255 Link: https://sources.debian.org/src/nodejs/12.22.12~dfsg-1~deb11u3/debian/patches/cve-2022-35255.patch Signed-off-by: Poonam Jadhav <Poonam.Jadhav@kpit.com> Signed-off-by: Omkar Patil <omkarpatil10.93@gmail.com> Signed-off-by: Armin Kuster <akuster808@gmail.com>
-rw-r--r--meta-oe/recipes-devtools/nodejs/nodejs/CVE-2022-35255.patch237
-rw-r--r--meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb1
2 files changed, 238 insertions, 0 deletions
diff --git a/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2022-35255.patch b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2022-35255.patch
new file mode 100644
index 0000000000..e9c2e7404a
--- /dev/null
+++ b/meta-oe/recipes-devtools/nodejs/nodejs/CVE-2022-35255.patch
@@ -0,0 +1,237 @@
1Origin: https://github.com/nodejs/node/commit/0c2a5723beff39d1f62daec96b5389da3d427e79
2Reviewed-by: Aron Xu <aron@debian.org>
3Last-Update: 2022-01-05
4Comment:
5 Although WebCrypto is not implemented in 12.x series, this fix is introducing
6 enhancment to the crypto setup of V8:EntropySource().
7
8commit 0c2a5723beff39d1f62daec96b5389da3d427e79
9Author: Ben Noordhuis <info@bnoordhuis.nl>
10Date: Sun Sep 11 10:48:34 2022 +0200
11
12 crypto: fix weak randomness in WebCrypto keygen
13
14 Commit dae283d96f from August 2020 introduced a call to EntropySource()
15 in SecretKeyGenTraits::DoKeyGen() in src/crypto/crypto_keygen.cc. There
16 are two problems with that:
17
18 1. It does not check the return value, it assumes EntropySource() always
19 succeeds, but it can (and sometimes will) fail.
20
21 2. The random data returned byEntropySource() may not be
22 cryptographically strong and therefore not suitable as keying
23 material.
24
25 An example is a freshly booted system or a system without /dev/random or
26 getrandom(2).
27
28 EntropySource() calls out to openssl's RAND_poll() and RAND_bytes() in a
29 best-effort attempt to obtain random data. OpenSSL has a built-in CSPRNG
30 but that can fail to initialize, in which case it's possible either:
31
32 1. No random data gets written to the output buffer, i.e., the output is
33 unmodified, or
34
35 2. Weak random data is written. It's theoretically possible for the
36 output to be fully predictable because the CSPRNG starts from a
37 predictable state.
38
39 Replace EntropySource() and CheckEntropy() with new function CSPRNG()
40 that enforces checking of the return value. Abort on startup when the
41 entropy pool fails to initialize because that makes it too easy to
42 compromise the security of the process.
43
44 Refs: https://hackerone.com/bugs?report_id=1690000
45 Refs: https://github.com/nodejs/node/pull/35093
46
47 Reviewed-By: Rafael Gonzaga <rafael.nunu@hotmail.com>
48 Reviewed-By: Tobias Nießen <tniessen@tnie.de>
49 PR-URL: #346
50 Backport-PR-URL: #351
51 CVE-ID: CVE-2022-35255
52
53CVE: CVE-2022-35255
54Upstream-Status: Backport [https://sources.debian.org/src/nodejs/12.22.12~dfsg-1~deb11u3/debian/patches/cve-2022-35255.patch]
55Comment: No hunks refreshed
56Signed-off-by: Poonam Jadhav <Poonam.Jadhav@kpit.com>
57
58Index: nodejs-12.22.12~dfsg/node.gyp
59===================================================================
60--- nodejs-12.22.12~dfsg.orig/node.gyp
61+++ nodejs-12.22.12~dfsg/node.gyp
62@@ -743,6 +743,8 @@
63 'openssl_default_cipher_list%': '',
64 },
65
66+ 'cflags': ['-Werror=unused-result'],
67+
68 'defines': [
69 'NODE_ARCH="<(target_arch)"',
70 'NODE_PLATFORM="<(OS)"',
71Index: nodejs-12.22.12~dfsg/src/node_crypto.cc
72===================================================================
73--- nodejs-12.22.12~dfsg.orig/src/node_crypto.cc
74+++ nodejs-12.22.12~dfsg/src/node_crypto.cc
75@@ -386,48 +386,14 @@ void ThrowCryptoError(Environment* env,
76 env->isolate()->ThrowException(exception);
77 }
78
79+MUST_USE_RESULT CSPRNGResult CSPRNG(void* buffer, size_t length) {
80+ do {
81+ if (1 == RAND_status())
82+ if (1 == RAND_bytes(static_cast<unsigned char*>(buffer), length))
83+ return {true};
84+ } while (1 == RAND_poll());
85
86-// Ensure that OpenSSL has enough entropy (at least 256 bits) for its PRNG.
87-// The entropy pool starts out empty and needs to fill up before the PRNG
88-// can be used securely. Once the pool is filled, it never dries up again;
89-// its contents is stirred and reused when necessary.
90-//
91-// OpenSSL normally fills the pool automatically but not when someone starts
92-// generating random numbers before the pool is full: in that case OpenSSL
93-// keeps lowering the entropy estimate to thwart attackers trying to guess
94-// the initial state of the PRNG.
95-//
96-// When that happens, we will have to wait until enough entropy is available.
97-// That should normally never take longer than a few milliseconds.
98-//
99-// OpenSSL draws from /dev/random and /dev/urandom. While /dev/random may
100-// block pending "true" randomness, /dev/urandom is a CSPRNG that doesn't
101-// block under normal circumstances.
102-//
103-// The only time when /dev/urandom may conceivably block is right after boot,
104-// when the whole system is still low on entropy. That's not something we can
105-// do anything about.
106-inline void CheckEntropy() {
107- for (;;) {
108- int status = RAND_status();
109- CHECK_GE(status, 0); // Cannot fail.
110- if (status != 0)
111- break;
112-
113- // Give up, RAND_poll() not supported.
114- if (RAND_poll() == 0)
115- break;
116- }
117-}
118-
119-
120-bool EntropySource(unsigned char* buffer, size_t length) {
121- // Ensure that OpenSSL's PRNG is properly seeded.
122- CheckEntropy();
123- // RAND_bytes() can return 0 to indicate that the entropy data is not truly
124- // random. That's okay, it's still better than V8's stock source of entropy,
125- // which is /dev/urandom on UNIX platforms and the current time on Windows.
126- return RAND_bytes(buffer, length) != -1;
127+ return {false};
128 }
129
130 void SecureContext::Initialize(Environment* env, Local<Object> target) {
131@@ -649,9 +615,9 @@ void SecureContext::Init(const FunctionC
132 // OpenSSL 1.1.0 changed the ticket key size, but the OpenSSL 1.0.x size was
133 // exposed in the public API. To retain compatibility, install a callback
134 // which restores the old algorithm.
135- if (RAND_bytes(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)) <= 0 ||
136- RAND_bytes(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)) <= 0 ||
137- RAND_bytes(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)) <= 0) {
138+ if (CSPRNG(sc->ticket_key_name_, sizeof(sc->ticket_key_name_)).is_err() ||
139+ CSPRNG(sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_)).is_err() ||
140+ CSPRNG(sc->ticket_key_aes_, sizeof(sc->ticket_key_aes_)).is_err()) {
141 return env->ThrowError("Error generating ticket keys");
142 }
143 SSL_CTX_set_tlsext_ticket_key_cb(sc->ctx_.get(), TicketCompatibilityCallback);
144@@ -1643,7 +1609,7 @@ int SecureContext::TicketCompatibilityCa
145
146 if (enc) {
147 memcpy(name, sc->ticket_key_name_, sizeof(sc->ticket_key_name_));
148- if (RAND_bytes(iv, 16) <= 0 ||
149+ if (CSPRNG(iv, 16).is_err() ||
150 EVP_EncryptInit_ex(ectx, EVP_aes_128_cbc(), nullptr,
151 sc->ticket_key_aes_, iv) <= 0 ||
152 HMAC_Init_ex(hctx, sc->ticket_key_hmac_, sizeof(sc->ticket_key_hmac_),
153@@ -5867,8 +5833,7 @@ struct RandomBytesJob : public CryptoJob
154 : CryptoJob(env), rc(Nothing<int>()) {}
155
156 inline void DoThreadPoolWork() override {
157- CheckEntropy(); // Ensure that OpenSSL's PRNG is properly seeded.
158- rc = Just(RAND_bytes(data, size));
159+ rc = Just(int(CSPRNG(data, size).is_ok()));
160 if (0 == rc.FromJust()) errors.Capture();
161 }
162
163@@ -6318,8 +6283,8 @@ class GenerateKeyPairJob : public Crypto
164 }
165
166 inline bool GenerateKey() {
167- // Make sure that the CSPRNG is properly seeded so the results are secure.
168- CheckEntropy();
169+ // Make sure that the CSPRNG is properly seeded.
170+ CHECK(CSPRNG(nullptr, 0).is_ok());
171
172 // Create the key generation context.
173 EVPKeyCtxPointer ctx = config_->Setup();
174Index: nodejs-12.22.12~dfsg/src/node_crypto.h
175===================================================================
176--- nodejs-12.22.12~dfsg.orig/src/node_crypto.h
177+++ nodejs-12.22.12~dfsg/src/node_crypto.h
178@@ -840,7 +840,19 @@ class ECDH final : public BaseObject {
179 const EC_GROUP* group_;
180 };
181
182-bool EntropySource(unsigned char* buffer, size_t length);
183+struct CSPRNGResult {
184+ const bool ok;
185+ MUST_USE_RESULT bool is_ok() const { return ok; }
186+ MUST_USE_RESULT bool is_err() const { return !ok; }
187+};
188+
189+// Either succeeds with exactly |length| bytes of cryptographically
190+// strong pseudo-random data, or fails. This function may block.
191+// Don't assume anything about the contents of |buffer| on error.
192+// As a special case, |length == 0| can be used to check if the CSPRNG
193+// is properly seeded without consuming entropy.
194+MUST_USE_RESULT CSPRNGResult CSPRNG(void* buffer, size_t length);
195+
196 #ifndef OPENSSL_NO_ENGINE
197 void SetEngine(const v8::FunctionCallbackInfo<v8::Value>& args);
198 #endif // !OPENSSL_NO_ENGINE
199Index: nodejs-12.22.12~dfsg/src/inspector_io.cc
200===================================================================
201--- nodejs-12.22.12~dfsg.orig/src/inspector_io.cc
202+++ nodejs-12.22.12~dfsg/src/inspector_io.cc
203@@ -46,8 +46,7 @@ std::string ScriptPath(uv_loop_t* loop,
204 // Used ver 4 - with numbers
205 std::string GenerateID() {
206 uint16_t buffer[8];
207- CHECK(crypto::EntropySource(reinterpret_cast<unsigned char*>(buffer),
208- sizeof(buffer)));
209+ CHECK(crypto::CSPRNG(buffer, sizeof(buffer)).is_ok());
210
211 char uuid[256];
212 snprintf(uuid, sizeof(uuid), "%04x%04x-%04x-%04x-%04x-%04x%04x%04x",
213Index: nodejs-12.22.12~dfsg/src/node.cc
214===================================================================
215--- nodejs-12.22.12~dfsg.orig/src/node.cc
216+++ nodejs-12.22.12~dfsg/src/node.cc
217@@ -969,9 +969,17 @@ InitializationResult InitializeOncePerPr
218 // the random source is properly initialized first.
219 OPENSSL_init();
220 #endif // NODE_FIPS_MODE
221- // V8 on Windows doesn't have a good source of entropy. Seed it from
222- // OpenSSL's pool.
223- V8::SetEntropySource(crypto::EntropySource);
224+ // Ensure CSPRNG is properly seeded.
225+ CHECK(crypto::CSPRNG(nullptr, 0).is_ok());
226+
227+ V8::SetEntropySource([](unsigned char* buffer, size_t length) {
228+ // V8 falls back to very weak entropy when this function fails
229+ // and /dev/urandom isn't available. That wouldn't be so bad if
230+ // the entropy was only used for Math.random() but it's also used for
231+ // hash table and address space layout randomization. Better to abort.
232+ CHECK(crypto::CSPRNG(buffer, length).is_ok());
233+ return true;
234+ });
235 #endif // HAVE_OPENSSL
236
237 per_process::v8_platform.Initialize(
diff --git a/meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb b/meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb
index 2258cb1086..df9c6010eb 100644
--- a/meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb
+++ b/meta-oe/recipes-devtools/nodejs/nodejs_12.22.12.bb
@@ -23,6 +23,7 @@ SRC_URI = "http://nodejs.org/dist/v${PV}/node-v${PV}.tar.xz \
23 file://mips-warnings.patch \ 23 file://mips-warnings.patch \
24 file://0001-Remove-use-of-register-r7-because-llvm-now-issues-an.patch \ 24 file://0001-Remove-use-of-register-r7-because-llvm-now-issues-an.patch \
25 file://CVE-2022-32212.patch \ 25 file://CVE-2022-32212.patch \
26 file://CVE-2022-35255.patch \
26 " 27 "
27SRC_URI_append_class-target = " \ 28SRC_URI_append_class-target = " \
28 file://0002-Using-native-binaries.patch \ 29 file://0002-Using-native-binaries.patch \