From 5efd0aa3997f7e9ceaeacd653e6b5785f05c10fc Mon Sep 17 00:00:00 2001
From: David Benjamin <davidben@google.com>
Date: Fri, 25 Jan 2019 04:34:38 +0000
Subject: [PATCH] tls: fix malloc mismatch in SSL_set_tlsext_status_ocsp_resp
 call

SSL_set_tlsext_status_ocsp_resp expects the data to be allocated with
OPENSSL_malloc, not libc malloc, so use OpenSSLMalloc.

Additionally, though OpenSSL doesn't type-check due to it being a macro,
the function is documented to take an unsigned char pointer:
https://www.openssl.org/docs/man1.1.0/ssl/SSL_set_tlsext_status_ocsp_resp.html

(By default, OPENSSL_malloc is the same as libc malloc, but it is
possible to customize this.)

PR-URL: https://github.com/nodejs/node/pull/25706
Reviewed-By: Sam Roberts <vieuxtech@gmail.com>
Reviewed-By: Ali Ijaz Sheikh <ofrobots@google.com>
Reviewed-By: Anna Henningsen <anna@addaleax.net>
Reviewed-By: James M Snell <jasnell@gmail.com>
---
 src/node_crypto.cc | 13 ++++++++++---
 1 file changed, 10 insertions(+), 3 deletions(-)

diff --git a/src/node_crypto.cc b/src/node_crypto.cc
index cdb60f048f3..0c32feb2e10 100644
--- a/src/node_crypto.cc
+++ b/src/node_crypto.cc
@@ -323,6 +323,14 @@ bool EntropySource(unsigned char* buffer, size_t length) {
 }
 
 
+template <typename T>
+static T* MallocOpenSSL(size_t count) {
+  void* mem = OPENSSL_malloc(MultiplyWithOverflowCheck(count, sizeof(T)));
+  CHECK_IMPLIES(mem == nullptr, count == 0);
+  return static_cast<T*>(mem);
+}
+
+
 void SecureContext::Initialize(Environment* env, Local<Object> target) {
   Local<FunctionTemplate> t = env->NewFunctionTemplate(New);
   t->InstanceTemplate()->SetInternalFieldCount(1);
@@ -2356,12 +2364,11 @@ int SSLWrap<Base>::TLSExtStatusCallback(SSL* s, void* arg) {
     size_t len = Buffer::Length(obj);
 
     // OpenSSL takes control of the pointer after accepting it
-    auto* allocator = env->isolate()->GetArrayBufferAllocator();
-    uint8_t* data = static_cast<uint8_t*>(allocator->AllocateUninitialized(len));
+    unsigned char* data = MallocOpenSSL<unsigned char>(len);
     memcpy(data, resp, len);
 
     if (!SSL_set_tlsext_status_ocsp_resp(s, data, len))
-      allocator->Free(data, len);
+      OPENSSL_free(data);
     w->ocsp_response_.Reset();
 
     return SSL_TLSEXT_ERR_OK;