Skip to content

Commit 35b14ab

Browse files
joyeecheungbmeck
authored andcommitted
src: return non-empty data in context data serializer
For pointer values in the context data, we need to return non-empty data in the serializer so that V8 does not serialize them verbatim, making the snapshot unreproducible. PR-URL: nodejs#50983 Refs: nodejs/build#3043 Reviewed-By: Daniel Lemire <[email protected]> Reviewed-By: James M Snell <[email protected]>
1 parent 03e23de commit 35b14ab

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

src/node_snapshotable.cc

+26-8
Original file line numberDiff line numberDiff line change
@@ -1262,18 +1262,30 @@ void DeserializeNodeContextData(Local<Context> holder,
12621262
int index,
12631263
StartupData payload,
12641264
void* callback_data) {
1265-
// This is unreachable for now. We will reset all the pointers in
1266-
// Environment::AssignToContext() via the realm constructor.
1267-
UNREACHABLE();
1265+
// We will reset all the pointers in Environment::AssignToContext()
1266+
// via the realm constructor.
1267+
switch (index) {
1268+
case ContextEmbedderIndex::kEnvironment:
1269+
case ContextEmbedderIndex::kContextifyContext:
1270+
case ContextEmbedderIndex::kRealm:
1271+
case ContextEmbedderIndex::kContextTag: {
1272+
uint64_t index_64;
1273+
int size = sizeof(index_64);
1274+
CHECK_EQ(payload.raw_size, size);
1275+
memcpy(&index_64, payload.data, payload.raw_size);
1276+
CHECK_EQ(index_64, static_cast<uint64_t>(index));
1277+
break;
1278+
}
1279+
default:
1280+
UNREACHABLE();
1281+
}
12681282
}
12691283

12701284
StartupData SerializeNodeContextData(Local<Context> holder,
12711285
int index,
12721286
void* callback_data) {
1273-
// For now we just reset all of them in Environment::AssignToContext().
1274-
// We return empty data here to make sure that the embedder data serialized
1275-
// into the snapshot is reproducible and V8 doesn't have to try to serialize
1276-
// the pointer values that won't be useful during deserialization.
1287+
// For pointer values, we need to return some non-empty data so that V8
1288+
// does not serialize them verbatim, making the snapshot unreproducible.
12771289
switch (index) {
12781290
case ContextEmbedderIndex::kEnvironment:
12791291
case ContextEmbedderIndex::kContextifyContext:
@@ -1286,7 +1298,13 @@ StartupData SerializeNodeContextData(Local<Context> holder,
12861298
static_cast<int>(index),
12871299
*holder,
12881300
data);
1289-
return {nullptr, 0};
1301+
// We use uint64_t to avoid padding.
1302+
uint64_t index_64 = static_cast<uint64_t>(index);
1303+
// It must be allocated with new[] because V8 will call delete[] on it.
1304+
size_t size = sizeof(index_64);
1305+
char* startup_data = new char[size];
1306+
memcpy(startup_data, &index_64, size);
1307+
return {startup_data, static_cast<int>(size)};
12901308
}
12911309
default:
12921310
UNREACHABLE();

0 commit comments

Comments
 (0)