Commit 63e054f5 authored by Samuel Groß's avatar Samuel Groß Committed by V8 LUCI CQ

[sandbox] Fix serialization of raw external references

When testing the serializer (e.g. via --stress-snapshot), raw external
references (i.e. just raw pointers) can be embedded inside the snapshot.
When those pointers are sandboxed, the corresponding external pointer
tag also needs to be encoded in the snapshot. This CL adds the necessary
logic to support this by introducing new serializer Bytecodes for raw
external references and encoding the raw pointers together with the tag.

Bug: v8:10391
Change-Id: I7b3710c2144e19f7507e3f6db537d250d102ee28
Cq-Include-Trybots: luci.v8.try:v8_linux64_heap_sandbox_dbg_ng,v8_linux_arm64_sim_heap_sandbox_dbg_ng
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3762575Reviewed-by: 's avatarLeszek Swirski <leszeks@chromium.org>
Commit-Queue: Samuel Groß <saelo@chromium.org>
Cr-Commit-Position: refs/heads/main@{#81723}
parent 0ef8ce7d
...@@ -977,6 +977,20 @@ int Deserializer<IsolateT>::ReadSingleBytecodeData(byte data, ...@@ -977,6 +977,20 @@ int Deserializer<IsolateT>::ReadSingleBytecodeData(byte data,
address, tag); address, tag);
} }
case kSandboxedRawExternalReference:
case kRawExternalReference: {
DCHECK_IMPLIES(data == kSandboxedExternalReference,
V8_ENABLE_SANDBOX_BOOL);
Address address;
source_.CopyRaw(&address, kSystemPointerSize);
ExternalPointerTag tag = kExternalPointerNullTag;
if (data == kSandboxedRawExternalReference) {
tag = ReadExternalPointerTag();
}
return WriteExternalPointer(slot_accessor.external_pointer_slot(),
address, tag);
}
case kInternalReference: case kInternalReference:
case kOffHeapTarget: case kOffHeapTarget:
// These bytecodes are expected only during RelocInfo iteration. // These bytecodes are expected only during RelocInfo iteration.
......
...@@ -34,8 +34,6 @@ class SerializerDeserializer : public RootVisitor { ...@@ -34,8 +34,6 @@ class SerializerDeserializer : public RootVisitor {
// clang-format off // clang-format off
#define UNUSED_SERIALIZER_BYTE_CODES(V) \ #define UNUSED_SERIALIZER_BYTE_CODES(V) \
/* Free range 0x1e..0x1f */ \
V(0x1e) V(0x1f) \
/* Free range 0x20..0x2f */ \ /* Free range 0x20..0x2f */ \
V(0x20) V(0x21) V(0x22) V(0x23) V(0x24) V(0x25) V(0x26) V(0x27) \ V(0x20) V(0x21) V(0x22) V(0x23) V(0x24) V(0x25) V(0x26) V(0x27) \
V(0x28) V(0x29) V(0x2a) V(0x2b) V(0x2c) V(0x2d) V(0x2e) V(0x2f) \ V(0x28) V(0x29) V(0x2a) V(0x2b) V(0x2c) V(0x2d) V(0x2e) V(0x2f) \
...@@ -82,7 +80,7 @@ class SerializerDeserializer : public RootVisitor { ...@@ -82,7 +80,7 @@ class SerializerDeserializer : public RootVisitor {
enum Bytecode : byte { enum Bytecode : byte {
// //
// ---------- byte code range 0x00..0x1d ---------- // ---------- byte code range 0x00..0x1f ----------
// //
// 0x00..0x03 Allocate new object, in specified space. // 0x00..0x03 Allocate new object, in specified space.
...@@ -122,12 +120,18 @@ class SerializerDeserializer : public RootVisitor { ...@@ -122,12 +120,18 @@ class SerializerDeserializer : public RootVisitor {
kApiReference, kApiReference,
// External reference referenced by id. // External reference referenced by id.
kExternalReference, kExternalReference,
// Same as two bytecodes above but for serializing sandboxed external // External reference encoded as raw pointer. Can only be used when the
// snapshot will be deserialized again in the same Isolate, and so is only
// useful for testing. This is currently unused as unsandboxed raw external
// references are encoded as FixedRawData instead.
kRawExternalReference,
// Same as three bytecodes above but for serializing sandboxed external
// pointer values. // pointer values.
// TODO(v8:10391): Remove them once all ExternalPointer usages are // TODO(v8:10391): Remove them once all ExternalPointer usages are
// sandbox-ready. // sandbox-ready.
kSandboxedApiReference, kSandboxedApiReference,
kSandboxedExternalReference, kSandboxedExternalReference,
kSandboxedRawExternalReference,
// Internal reference of a code objects in code stream. // Internal reference of a code objects in code stream.
kInternalReference, kInternalReference,
// In-place weak references. // In-place weak references.
......
...@@ -974,9 +974,19 @@ void Serializer::ObjectSerializer::OutputExternalReference( ...@@ -974,9 +974,19 @@ void Serializer::ObjectSerializer::OutputExternalReference(
CHECK(serializer_->allow_unknown_external_references_for_testing()); CHECK(serializer_->allow_unknown_external_references_for_testing());
CHECK(IsAligned(target_size, kTaggedSize)); CHECK(IsAligned(target_size, kTaggedSize));
CHECK_LE(target_size, kFixedRawDataCount * kTaggedSize); CHECK_LE(target_size, kFixedRawDataCount * kTaggedSize);
int size_in_tagged = target_size >> kTaggedSizeLog2; if (sandboxify) {
sink_->Put(FixedRawDataWithSize::Encode(size_in_tagged), "FixedRawData"); CHECK_EQ(target_size, kSystemPointerSize);
sink_->PutRaw(reinterpret_cast<byte*>(&target), target_size, "Bytes"); sink_->Put(kSandboxedRawExternalReference, "SandboxedRawReference");
sink_->PutRaw(reinterpret_cast<byte*>(&target), target_size,
"raw pointer");
} else {
// Encode as FixedRawData instead of RawExternalReference as the target
// may be less than kSystemPointerSize large.
int size_in_tagged = target_size >> kTaggedSizeLog2;
sink_->Put(FixedRawDataWithSize::Encode(size_in_tagged), "FixedRawData");
sink_->PutRaw(reinterpret_cast<byte*>(&target), target_size,
"raw pointer");
}
} else if (encoded_reference.is_from_api()) { } else if (encoded_reference.is_from_api()) {
if (sandboxify) { if (sandboxify) {
sink_->Put(kSandboxedApiReference, "SandboxedApiRef"); sink_->Put(kSandboxedApiReference, "SandboxedApiRef");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment