[ext-code-space] Fix UB when accessing CodeDataContainer::code

... because of unaligned field address. The fix is to load code cage
base and the tagged value separately and then decompress - the same way
as it's done in the relaxed accessors of the code field.

Bug: v8:11880
Change-Id: Ia4699458e6a00ee16efea06c48cc5c67a82b22f7
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3416999
Auto-Submit: Igor Sheludko <ishell@chromium.org>
Reviewed-by: Dominik Inführ <dinfuehr@chromium.org>
Commit-Queue: Dominik Inführ <dinfuehr@chromium.org>
Cr-Commit-Position: refs/heads/main@{#78801}
This commit is contained in:
Igor Sheludko 2022-01-26 21:33:48 +01:00 committed by V8 LUCI CQ
parent 54604990c6
commit 281140c05c
2 changed files with 9 additions and 9 deletions

View File

@ -81,6 +81,7 @@ Handle<CodeDataContainer> FactoryBase<Impl>::NewCodeDataContainer(
SKIP_WRITE_BARRIER); SKIP_WRITE_BARRIER);
data_container.set_kind_specific_flags(flags, kRelaxedStore); data_container.set_kind_specific_flags(flags, kRelaxedStore);
if (V8_EXTERNAL_CODE_SPACE_BOOL) { if (V8_EXTERNAL_CODE_SPACE_BOOL) {
data_container.set_code_cage_base(impl()->isolate()->code_cage_base());
Isolate* isolate_for_heap_sandbox = impl()->isolate_for_heap_sandbox(); Isolate* isolate_for_heap_sandbox = impl()->isolate_for_heap_sandbox();
data_container.AllocateExternalPointerEntries(isolate_for_heap_sandbox); data_container.AllocateExternalPointerEntries(isolate_for_heap_sandbox);
data_container.set_raw_code(Smi::zero(), SKIP_WRITE_BARRIER); data_container.set_raw_code(Smi::zero(), SKIP_WRITE_BARRIER);

View File

@ -879,21 +879,20 @@ static_assert(!V8_EXTERNAL_CODE_SPACE_BOOL,
"for big endian architectures"); "for big endian architectures");
#endif #endif
DEF_GETTER(CodeDataContainer, raw_code, Object) { Object CodeDataContainer::raw_code() const {
PtrComprCageBase cage_base = code_cage_base();
return CodeDataContainer::raw_code(cage_base);
}
Object CodeDataContainer::raw_code(PtrComprCageBase cage_base) const {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// Given the fields layout we can write the Code reference as a full word Object value = TaggedField<Object, kCodeOffset>::load(cage_base, *this);
// (see the static asserts above).
Address* p = reinterpret_cast<Address*>(address() + kCodeOffset);
Object value = Object(*p);
return value; return value;
} }
void CodeDataContainer::set_raw_code(Object value, WriteBarrierMode mode) { void CodeDataContainer::set_raw_code(Object value, WriteBarrierMode mode) {
CHECK(V8_EXTERNAL_CODE_SPACE_BOOL); CHECK(V8_EXTERNAL_CODE_SPACE_BOOL);
// Given the fields layout we can write the Code reference as a full word TaggedField<Object, kCodeOffset>::store(*this, value);
// (see the static asserts above).
Address* p = reinterpret_cast<Address*>(address() + kCodeOffset);
*p = value.ptr();
CONDITIONAL_WRITE_BARRIER(*this, kCodeOffset, value, mode); CONDITIONAL_WRITE_BARRIER(*this, kCodeOffset, value, mode);
} }