From 584beaa2edc22ca30f3dbf896547cc2b4d90e3a1 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 55a65deeea6e74..32371a69588ce7 100644 --- a/src/node_snapshotable.cc +++ b/src/node_snapshotable.cc @@ -1357,9 +1357,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 5e281b8155c810..4ae52d8f3ae747 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);