Fix: PanelType unregister potential use-after-free
There are two issues here. First, the instanced panel freeing uses the panel type after it's been freed a few lines up in this function. Second, while panel types are registered for a single space type, there are cases where they're used in multiple space/region types anyway. Because of that, removing the dangling pointer of the freed type from just the registered region & space type combination isn't enough, we need to process all regions. Pull Request: https://projects.blender.org/blender/blender/pulls/129676
This commit is contained in:
@@ -211,31 +211,25 @@ static bool rna_Panel_unregister(Main *bmain, StructRNA *type)
|
||||
child_pt->parent = nullptr;
|
||||
}
|
||||
|
||||
const char space_type = pt->space_type;
|
||||
BLI_freelistN(&pt->children);
|
||||
BLI_freelinkN(&art->paneltypes, pt);
|
||||
|
||||
LISTBASE_FOREACH (bScreen *, screen, &bmain->screens) {
|
||||
LISTBASE_FOREACH (ScrArea *, area, &screen->areabase) {
|
||||
LISTBASE_FOREACH (SpaceLink *, sl, &area->spacedata) {
|
||||
if (sl->spacetype == space_type) {
|
||||
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase :
|
||||
&sl->regionbase;
|
||||
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
||||
if (region->type == art) {
|
||||
LISTBASE_FOREACH (Panel *, panel, ®ion->panels) {
|
||||
panel_type_clear_recursive(panel, pt);
|
||||
}
|
||||
}
|
||||
/* The unregistered panel might have had a template that added instanced panels,
|
||||
* so remove them just in case. They can be re-added on redraw anyway. */
|
||||
UI_panels_free_instanced(nullptr, region);
|
||||
ListBase *regionbase = (sl == area->spacedata.first) ? &area->regionbase : &sl->regionbase;
|
||||
LISTBASE_FOREACH (ARegion *, region, regionbase) {
|
||||
LISTBASE_FOREACH (Panel *, panel, ®ion->panels) {
|
||||
panel_type_clear_recursive(panel, pt);
|
||||
}
|
||||
/* The unregistered panel might have had a template that added instanced panels,
|
||||
* so remove them just in case. They can be re-added on redraw anyway. */
|
||||
UI_panels_free_instanced(nullptr, region);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BLI_freelistN(&pt->children);
|
||||
BLI_freelinkN(&art->paneltypes, pt);
|
||||
|
||||
/* update while blender is running */
|
||||
WM_main_add_notifier(NC_WINDOW, nullptr);
|
||||
return true;
|
||||
|
||||
Reference in New Issue
Block a user