Skip to content

Commit 22abbd2

Browse files
committed
Fix a bug in hidden class deletion.
We were leaving the isa pointer pointing to the deleted class and were then following its super_class pointer, both of which are potentially serious. This didn't show up on FreeBSD, because the relevant memory was always returned to a thread-local pool and the accesses were immediately afterwards, so it always worked. It broke with malloc implementations that were more aggressive about checking for use-after-free.
1 parent 0ae4e4c commit 22abbd2

File tree

2 files changed

+7
-3
lines changed

2 files changed

+7
-3
lines changed

associate.m

+1
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,7 @@ static void deallocHiddenClass(id obj, SEL _cmd)
274274
sub = sub->sibling_class;
275275
}
276276
}
277+
obj->isa = hiddenClass->super_class;
277278
// Free the class
278279
free(hiddenClass);
279280
}

runtime.c

+6-3
Original file line numberDiff line numberDiff line change
@@ -40,11 +40,14 @@ PRIVATE void call_cxx_destruct(id obj)
4040

4141
while (cls)
4242
{
43-
if (cls->cxx_destruct)
43+
// If we're deallocating a class with a hidden class, then the
44+
// `.cxx_destruct` method may deallocate the class.
45+
Class currentClass = cls;
46+
cls = cls->super_class;
47+
if (currentClass->cxx_destruct)
4448
{
45-
cls->cxx_destruct(obj, cxx_destruct);
49+
currentClass->cxx_destruct(obj, cxx_destruct);
4650
}
47-
cls = cls->super_class;
4851
}
4952
}
5053

0 commit comments

Comments
 (0)