Commit e1108083 authored by Patrick Thier's avatar Patrick Thier Committed by V8 LUCI CQ

[sandbox] Mark External String Resources from Client Heaps

External pointers used in external strings are always stored in the
shared external pointer table.
Prior to this CL we didn't mark external pointer entries for external
strings residing in client heaps.

Bug: v8:13260
Change-Id: Ifc5dc86f4ebe2791bfb8c4c8fe2673886d24e8a8
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3875028Reviewed-by: 's avatarDominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Patrick Thier <pthier@chromium.org>
Cr-Commit-Position: refs/heads/main@{#83016}
parent 30821ad6
......@@ -1449,6 +1449,69 @@ class ExternalStringTableCleaner : public RootVisitor {
Heap* heap_;
};
#ifdef V8_ENABLE_SANDBOX
class MarkExternalPointerFromExternalStringTable : public RootVisitor {
public:
explicit MarkExternalPointerFromExternalStringTable(
ExternalPointerTable* shared_table)
: visitor(shared_table) {}
void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) override {
// Visit all HeapObject pointers in [start, end).
for (FullObjectSlot p = start; p < end; ++p) {
Object o = *p;
if (o.IsHeapObject()) {
HeapObject heap_object = HeapObject::cast(o);
if (heap_object.IsExternalString()) {
ExternalString string = ExternalString::cast(heap_object);
string.VisitExternalPointers(&visitor);
} else {
// The original external string may have been internalized.
DCHECK(o.IsThinString());
}
}
}
}
private:
class MarkExternalPointerTableVisitor : public ObjectVisitor {
public:
explicit MarkExternalPointerTableVisitor(ExternalPointerTable* table)
: table_(table) {}
void VisitExternalPointer(HeapObject host, ExternalPointerSlot slot,
ExternalPointerTag tag) override {
if (!IsSandboxedExternalPointerType(tag)) return;
DCHECK(IsSharedExternalPointerType(tag));
ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
table_->Mark(handle, slot.address());
}
void VisitPointers(HeapObject host, ObjectSlot start,
ObjectSlot end) override {
UNREACHABLE();
}
void VisitPointers(HeapObject host, MaybeObjectSlot start,
MaybeObjectSlot end) override {
UNREACHABLE();
}
void VisitCodePointer(HeapObject host, CodeObjectSlot slot) override {
UNREACHABLE();
}
void VisitCodeTarget(Code host, RelocInfo* rinfo) override {
UNREACHABLE();
}
void VisitEmbeddedPointer(Code host, RelocInfo* rinfo) override {
UNREACHABLE();
}
private:
ExternalPointerTable* table_;
};
MarkExternalPointerTableVisitor visitor;
};
#endif
// Implementation of WeakObjectRetainer for mark compact GCs. All marked objects
// are retained.
class MarkCompactWeakObjectRetainer : public WeakObjectRetainer {
......@@ -2271,6 +2334,17 @@ void MarkCompactCollector::MarkObjectsFromClientHeap(Isolate* client) {
table.Mark(handle, reinterpret_cast<Address>(handle_location));
}
#endif // V8_COMPRESS_POINTERS
#ifdef V8_ENABLE_SANDBOX
if (IsSandboxedExternalPointerType(kExternalStringResourceTag) ||
IsSandboxedExternalPointerType(kExternalStringResourceDataTag)) {
// All ExternalString resources are stored in the shared external pointer
// table. Mark entries from client heaps.
ExternalPointerTable& table = client->shared_external_pointer_table();
MarkExternalPointerFromExternalStringTable external_string_visitor(&table);
heap->external_string_table_.IterateAll(&external_string_visitor);
}
#endif // V8_ENABLE_SANDBOX
}
void MarkCompactCollector::VisitObject(HeapObject obj) {
......
......@@ -1108,6 +1108,15 @@ void ExternalString::InitExternalPointerFields(Isolate* isolate) {
kResourceDataOffset, isolate, kNullAddress);
}
void ExternalString::VisitExternalPointers(ObjectVisitor* visitor) const {
visitor->VisitExternalPointer(*this, RawExternalPointerField(kResourceOffset),
kExternalStringResourceTag);
if (is_uncached()) return;
visitor->VisitExternalPointer(*this,
RawExternalPointerField(kResourceDataOffset),
kExternalStringResourceDataTag);
}
DEF_GETTER(ExternalString, resource_as_address, Address) {
Isolate* isolate = GetIsolateForSandbox(*this);
return ReadExternalPointerField<kExternalStringResourceTag>(kResourceOffset,
......
......@@ -911,6 +911,7 @@ class ExternalString
kResourceOffset + FIELD_SIZE(kResourceOffset);
inline void InitExternalPointerFields(Isolate* isolate);
inline void VisitExternalPointers(ObjectVisitor* visitor) const;
// Return whether the external string data pointer is not cached.
inline bool is_uncached() const;
......
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