Skip to content

Commit ed4f113

Browse files
Fix Crash on Default Interface Methods Call
This is a port of dotnet/runtime#115306: In case of a generic interface, build_imt_slots calculate the vt_slot to find the index in the vtable for the implementation. Currently implementation assumed interface methods are either static and/or virtual, but it's possible to have private/sealed methods that won't end up as virtual methods in vtable. This case was handled when building the vtable, but we didn't handle that scenario when building the IMT slots, ending up with wrong vtable slot, potentially outside of allocated memory. In repro provided by dotnet/runtime#113958, the created vtable will have 5 slots, 4 from implementing Object and 1 from the implemented interface. When calculating the vt_slot in build_imt_slots we did however include the private DIM methods when calculating vtable slot, ending up with 4 + 3, slot 7, but vtable only allocated 5, so it will read outside allocated memory, and if it this turns out to be NULL, that will trigger assert, otherwise it will use random value, but since IMT slot will be patched with compiled method, the issue wouldn't manifest, at least not in the specific repro scenario. Fix makes sure we only count virtual methods in build_imt_slots vt_slot index, similar to previous fixes for static and non-virtual methods in non-generic interfaces:
1 parent 8699644 commit ed4f113

File tree

1 file changed

+1
-1
lines changed

1 file changed

+1
-1
lines changed

mono/metadata/object.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1571,7 +1571,7 @@ build_imt_slots (MonoClass *klass, MonoVTable *vt, MonoDomain *domain, gpointer*
15711571
method = mono_class_get_method_by_index (mono_class_get_generic_class (iface)->container_class, method_slot_in_interface);
15721572
if (m_method_is_static (method))
15731573
continue;
1574-
if (mono_method_get_imt_slot (method) != slot_num) {
1574+
if (m_method_is_virtual(method) && mono_method_get_imt_slot (method) != slot_num) {
15751575
vt_slot ++;
15761576
continue;
15771577
}

0 commit comments

Comments
 (0)