From 488a854cf5fcc014934361f87f48bf401da5ae4b Mon Sep 17 00:00:00 2001 From: Nora Dossche <7771979+ndossche@users.noreply.github.com> Date: Wed, 25 Feb 2026 14:56:28 +0100 Subject: [PATCH] crypto: fix handling of null BUF_MEM* in ToV8Value() The assignment to `bptr` calls `BIO_get_mem_ptr` which can fail and leave the `bptr` as nullptr. This then later causes a null pointer deref. This is inconsistent with uses of the similar function `BIO_get_mem_data` that do check its return value, e.g. `node::crypto::X509sToArrayOfStrings()`. Solve it by checking for a null pointer and handling the `Nothing` return value at the call sites. PR-URL: https://github.com/nodejs/node/pull/61885 Reviewed-By: James M Snell Reviewed-By: Anna Henningsen --- src/crypto/crypto_keys.cc | 9 ++++++++- src/crypto/crypto_x509.cc | 6 ++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/src/crypto/crypto_keys.cc b/src/crypto/crypto_keys.cc index e805a984322c83..2e571fc6ba5564 100644 --- a/src/crypto/crypto_keys.cc +++ b/src/crypto/crypto_keys.cc @@ -86,8 +86,15 @@ MaybeLocal ToV8Value( Environment* env, const BIOPointer& bio, const EVPKeyPointer::AsymmetricKeyEncodingConfig& config) { - if (!bio) return {}; + if (!bio) { + THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Invalid BIO pointer"); + return {}; + } BUF_MEM* bptr = bio; + if (!bptr) { + THROW_ERR_CRYPTO_OPERATION_FAILED(env, "Unable to create BUF_MEM pointer"); + return {}; + } if (config.format == EVPKeyPointer::PKFormatType::PEM) { // PEM is an ASCII format, so we will return it as a string. return String::NewFromUtf8( diff --git a/src/crypto/crypto_x509.cc b/src/crypto/crypto_x509.cc index f40f6dd4f2bcaf..6ac4dd2adb38b6 100644 --- a/src/crypto/crypto_x509.cc +++ b/src/crypto/crypto_x509.cc @@ -106,6 +106,8 @@ MaybeLocal ToV8Value(Local context, BIOPointer&& bio) { if (!bio) [[unlikely]] return {}; BUF_MEM* mem = bio; + if (!mem) [[unlikely]] + return {}; Local ret; if (!String::NewFromUtf8(Isolate::GetCurrent(), mem->data, @@ -120,6 +122,8 @@ MaybeLocal ToV8Value(Local context, const BIOPointer& bio) { if (!bio) [[unlikely]] return {}; BUF_MEM* mem = bio; + if (!mem) [[unlikely]] + return {}; Local ret; if (!String::NewFromUtf8(Isolate::GetCurrent(), mem->data, @@ -134,6 +138,8 @@ MaybeLocal ToBuffer(Environment* env, BIOPointer* bio) { if (bio == nullptr || !*bio) [[unlikely]] return {}; BUF_MEM* mem = *bio; + if (!mem) [[unlikely]] + return {}; #ifdef V8_ENABLE_SANDBOX // If the v8 sandbox is enabled, then all array buffers must be allocated // via the isolate. External buffers are not allowed. So, instead of wrapping