Skip to content

Commit

Permalink
JIT: fix out of bounds read during SPMI collection (#77147)
Browse files Browse the repository at this point in the history
When recording the profile data into the method context, SPMI was
assuming all data items were `sizeof(uintptr_t)` which is not guaranteed.
Use the proper size.

Fixes #76991.
  • Loading branch information
AndyAyersMS committed Oct 18, 2022
1 parent 0ba8b10 commit 618e890
Showing 1 changed file with 31 additions and 2 deletions.
33 changes: 31 additions & 2 deletions src/coreclr/tools/superpmi/superpmi-shared/methodcontext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5664,6 +5664,34 @@ HRESULT MethodContext::repAllocPgoInstrumentationBySchema(
return result;
}

// The following are from <pgo_formatprocessing.h> which we can't include.

static ICorJitInfo::PgoInstrumentationKind operator&(ICorJitInfo::PgoInstrumentationKind a, ICorJitInfo::PgoInstrumentationKind b)
{
return static_cast<ICorJitInfo::PgoInstrumentationKind>(static_cast<int>(a) & static_cast<int>(b));
}

static unsigned InstrumentationKindToSize(ICorJitInfo::PgoInstrumentationKind kind)
{
switch(kind & ICorJitInfo::PgoInstrumentationKind::MarshalMask)
{
case ICorJitInfo::PgoInstrumentationKind::None:
return 0;
case ICorJitInfo::PgoInstrumentationKind::FourByte:
return 4;
case ICorJitInfo::PgoInstrumentationKind::EightByte:
return 8;
case ICorJitInfo::PgoInstrumentationKind::TypeHandle:
case ICorJitInfo::PgoInstrumentationKind::MethodHandle:
return sizeof(uintptr_t);
default:
LogError("Unexpected pgo schema data size (kind = %d)", kind);
return 0;
}
}

// End of pseudo-include

void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd,
ICorJitInfo::PgoInstrumentationSchema** pSchema,
UINT32* pCountSchemaItems,
Expand All @@ -5683,13 +5711,14 @@ void MethodContext::recGetPgoInstrumentationResults(CORINFO_METHOD_HANDLE ftnHnd
size_t maxOffset = 0;
for (UINT32 i = 0; i < (*pCountSchemaItems); i++)
{
maxOffset = max(maxOffset, pInSchema[i].Offset + pInSchema[i].Count * sizeof(uintptr_t));

agnosticSchema[i].Offset = (DWORDLONG)pInSchema[i].Offset;
agnosticSchema[i].InstrumentationKind = (DWORD)pInSchema[i].InstrumentationKind;
agnosticSchema[i].ILOffset = (DWORD)pInSchema[i].ILOffset;
agnosticSchema[i].Count = (DWORD)pInSchema[i].Count;
agnosticSchema[i].Other = (DWORD)pInSchema[i].Other;

unsigned const dataSize = InstrumentationKindToSize(pInSchema[i].InstrumentationKind);
maxOffset = max(maxOffset, pInSchema[i].Offset + pInSchema[i].Count * dataSize);
}
value.schema_index = GetPgoInstrumentationResults->AddBuffer((unsigned char*)agnosticSchema, sizeof(Agnostic_PgoInstrumentationSchema) * (*pCountSchemaItems));
free(agnosticSchema);
Expand Down

0 comments on commit 618e890

Please sign in to comment.