Skip to content

Commit a53d81e

Browse files
alexmarkovCommit Queue
authored andcommitted
[vm] Fix out-of-bounds access to kernel library -1
Certain kinds of functions do not have corresponding kernel binary, so Function::KernelLibraryIndex() returns -1 for them. However, flow graph builder and scopes builder established reading of kernel binary for those functions, which was based on a typed data view created for a library -1 (treating some unrelated field from kernel component index as library offset). This change fixes this out-of-bounds access and avoids reading any kernel for these functions. TEST=ci Fixes #60369 Change-Id: I91717ec6ad905b71bab49d7b3b3f636bda19afb4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/417102 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Alexander Markov <[email protected]>
1 parent fd36ced commit a53d81e

File tree

4 files changed

+33
-13
lines changed

4 files changed

+33
-13
lines changed

runtime/vm/compiler/frontend/kernel_binary_flowgraph.cc

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -970,10 +970,13 @@ FlowGraph* StreamingFlowGraphBuilder::BuildGraph() {
970970
void StreamingFlowGraphBuilder::ParseKernelASTFunction() {
971971
const Function& function = parsed_function()->function();
972972

973-
const intptr_t kernel_offset = function.kernel_offset();
974-
ASSERT(kernel_offset >= 0);
975-
976-
SetOffset(kernel_offset);
973+
if (!function.IsNoSuchMethodDispatcher() &&
974+
!function.IsInvokeFieldDispatcher() &&
975+
!function.IsFfiCallbackTrampoline()) {
976+
const intptr_t kernel_offset = function.kernel_offset();
977+
ASSERT(kernel_offset >= 0);
978+
SetOffset(kernel_offset);
979+
}
977980

978981
// Mark forwarding stubs.
979982
switch (function.kind()) {

runtime/vm/compiler/frontend/scope_builder.cc

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -122,12 +122,17 @@ ScopeBuildingResult* ScopeBuilder::BuildScopes() {
122122

123123
parsed_function_->set_scope(scope_);
124124

125-
helper_.SetOffset(function.kernel_offset());
125+
ProcedureAttributesMetadata attrs;
126+
127+
if (!function.IsNoSuchMethodDispatcher() &&
128+
!function.IsInvokeFieldDispatcher() &&
129+
!function.IsFfiCallbackTrampoline()) {
130+
helper_.SetOffset(function.kernel_offset());
131+
attrs = procedure_attributes_metadata_helper_.GetProcedureAttributes(
132+
function.kernel_offset());
133+
}
126134

127135
FunctionNodeHelper function_node_helper(&helper_);
128-
const ProcedureAttributesMetadata attrs =
129-
procedure_attributes_metadata_helper_.GetProcedureAttributes(
130-
function.kernel_offset());
131136

132137
switch (function.kind()) {
133138
case UntaggedFunction::kImplicitClosureFunction: {

runtime/vm/kernel_binary.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -498,9 +498,14 @@ class Reader : public ValueObject {
498498
: thread_(nullptr), raw_buffer_(buffer), size_(size) {}
499499

500500
void Init() {
501-
ASSERT(typed_data_->IsExternalOrExternalView());
502-
raw_buffer_ = reinterpret_cast<uint8_t*>(typed_data_->DataAddr(0));
503-
size_ = typed_data_->LengthInBytes();
501+
if (typed_data_->IsNull()) {
502+
raw_buffer_ = nullptr;
503+
size_ = 0;
504+
} else {
505+
ASSERT(typed_data_->IsExternalOrExternalView());
506+
raw_buffer_ = reinterpret_cast<uint8_t*>(typed_data_->DataAddr(0));
507+
size_ = typed_data_->LengthInBytes();
508+
}
504509
offset_ = 0;
505510
}
506511

runtime/vm/object.cc

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11410,8 +11410,10 @@ KernelProgramInfoPtr Function::KernelProgramInfo() const {
1141011410
}
1141111411

1141211412
TypedDataViewPtr Function::KernelLibrary() const {
11413+
const intptr_t kernel_library_index = KernelLibraryIndex();
11414+
if (kernel_library_index == -1) return TypedDataView::null();
1141311415
const auto& info = KernelProgramInfo::Handle(KernelProgramInfo());
11414-
return info.KernelLibrary(KernelLibraryIndex());
11416+
return info.KernelLibrary(kernel_library_index);
1141511417
}
1141611418

1141711419
intptr_t Function::KernelLibraryOffset() const {
@@ -12419,8 +12421,10 @@ void Field::InheritKernelOffsetFrom(const Field& src) const {
1241912421

1242012422
#if !defined(DART_PRECOMPILED_RUNTIME)
1242112423
TypedDataViewPtr Field::KernelLibrary() const {
12424+
const intptr_t kernel_library_index = KernelLibraryIndex();
12425+
if (kernel_library_index == -1) return TypedDataView::null();
1242212426
const auto& info = KernelProgramInfo::Handle(KernelProgramInfo());
12423-
return info.KernelLibrary(KernelLibraryIndex());
12427+
return info.KernelLibrary(kernel_library_index);
1242412428
}
1242512429

1242612430
intptr_t Field::KernelLibraryOffset() const {
@@ -15685,6 +15689,7 @@ intptr_t KernelProgramInfo::KernelLibraryStartOffset(
1568515689
const intptr_t library_count =
1568615690
Utils::BigEndianToHost32(LoadUnaligned(reinterpret_cast<uint32_t*>(
1568715691
blob.DataAddr(blob.LengthInBytes() - 2 * 4))));
15692+
ASSERT((library_index >= 0) && (library_index < library_count));
1568815693
const intptr_t library_start =
1568915694
Utils::BigEndianToHost32(LoadUnaligned(reinterpret_cast<uint32_t*>(
1569015695
blob.DataAddr(blob.LengthInBytes() -
@@ -15694,6 +15699,7 @@ intptr_t KernelProgramInfo::KernelLibraryStartOffset(
1569415699

1569515700
TypedDataViewPtr KernelProgramInfo::KernelLibrary(
1569615701
intptr_t library_index) const {
15702+
ASSERT(library_index >= 0);
1569715703
const intptr_t start_offset = KernelLibraryStartOffset(library_index);
1569815704
const intptr_t end_offset = KernelLibraryEndOffset(library_index);
1569915705
const auto& component = TypedDataBase::Handle(kernel_component());
@@ -15706,6 +15712,7 @@ intptr_t KernelProgramInfo::KernelLibraryEndOffset(
1570615712
const intptr_t library_count =
1570715713
Utils::BigEndianToHost32(LoadUnaligned(reinterpret_cast<uint32_t*>(
1570815714
blob.DataAddr(blob.LengthInBytes() - 2 * 4))));
15715+
ASSERT((library_index >= 0) && (library_index < library_count));
1570915716
const intptr_t library_end = Utils::BigEndianToHost32(
1571015717
LoadUnaligned(reinterpret_cast<uint32_t*>(blob.DataAddr(
1571115718
blob.LengthInBytes() - (2 + (library_count - library_index)) * 4))));

0 commit comments

Comments
 (0)