From 1db5ac79676d972b3956078500cac0e20974da95 Mon Sep 17 00:00:00 2001 From: Joyee Cheung Date: Sun, 23 Jun 2024 21:36:10 +0200 Subject: [PATCH] src: zero-initialize data that are copied into the snapshot MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit To prevent padding from making the snapshot unreproducible, zero-initialize the data that are copied into the snapshot so that the padding copied are all zeros. This is better than enlarging the enums to align the fields since it doesn't make the snapshot bigger than necessary, and it removes the need of using static assertions to ensure alignment. PR-URL: https://github.com/nodejs/node/pull/53563 Refs: https://github.com/nodejs/node/pull/50983 Reviewed-By: Chengzhong Wu Reviewed-By: Tobias Nießen Reviewed-By: Richard Lau Reviewed-By: Daniel Lemire Reviewed-By: James M Snell --- src/node_snapshotable.cc | 4 +++- src/node_snapshotable.h | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/node_snapshotable.cc b/src/node_snapshotable.cc index d2ccbe8429048a..426066fb9d63d4 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -1415,9 +1415,11 @@ StartupData SerializeNodeContextInternalFields(Local holder, // To serialize the type field, save data in a EmbedderTypeInfo. if (index == BaseObject::kEmbedderType) { int size = sizeof(EmbedderTypeInfo); - char* data = new char[size]; // We need to use placement new because V8 calls delete[] on the returned // data. + // The () syntax at the end would zero-initialize the block and make + // the padding reproducible. + char* data = new char[size](); // TODO(joyeecheung): support cppgc objects. new (data) EmbedderTypeInfo(obj->type(), EmbedderTypeInfo::MemoryMode::kBaseObject); diff --git a/src/node_snapshotable.h b/src/node_snapshotable.h index 600e56c481be90..31be74bcfd568a 100644 --- a/src/node_snapshotable.h +++ b/src/node_snapshotable.h @@ -47,6 +47,7 @@ struct InternalFieldInfoBase { std::is_same_v, "Can only accept InternalFieldInfoBase subclasses"); void* buf = ::operator new[](sizeof(T)); + memset(buf, 0, sizeof(T)); // Make the padding reproducible. T* result = new (buf) T; result->type = type; result->length = sizeof(T);