mirror of
https://github.com/swaywm/sway.git
synced 2026-04-26 06:46:26 -04:00
Fix layer shell subsurface use after free
This occurs when a layer surface is destroyed , prompting an unmap event for all its children subsurfaces (if it has any). Since this happens after the parent surface is destroyed, any pointers to it will become dangling.
This commit is contained in:
parent
1dbb699036
commit
53e4a88bdb
2 changed files with 18 additions and 0 deletions
|
|
@ -48,6 +48,7 @@ struct sway_layer_subsurface {
|
|||
struct wl_listener unmap;
|
||||
struct wl_listener destroy;
|
||||
struct wl_listener commit;
|
||||
struct wl_listener layer_surface_destroy;
|
||||
};
|
||||
|
||||
struct sway_output;
|
||||
|
|
|
|||
|
|
@ -398,6 +398,8 @@ static void subsurface_damage(struct sway_layer_subsurface *subsurface,
|
|||
static void subsurface_handle_unmap(struct wl_listener *listener, void *data) {
|
||||
struct sway_layer_subsurface *subsurface =
|
||||
wl_container_of(listener, subsurface, unmap);
|
||||
if (subsurface->layer_surface == NULL)
|
||||
return;
|
||||
subsurface_damage(subsurface, true);
|
||||
}
|
||||
|
||||
|
|
@ -413,6 +415,14 @@ static void subsurface_handle_commit(struct wl_listener *listener, void *data) {
|
|||
subsurface_damage(subsurface, false);
|
||||
}
|
||||
|
||||
static void subsurface_handle_layer_surface_destroy(
|
||||
struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct sway_layer_subsurface *subsurface =
|
||||
wl_container_of(listener, subsurface, layer_surface_destroy);
|
||||
subsurface->layer_surface = NULL;
|
||||
}
|
||||
|
||||
static void subsurface_handle_destroy(struct wl_listener *listener,
|
||||
void *data) {
|
||||
struct sway_layer_subsurface *subsurface =
|
||||
|
|
@ -422,12 +432,14 @@ static void subsurface_handle_destroy(struct wl_listener *listener,
|
|||
wl_list_remove(&subsurface->unmap.link);
|
||||
wl_list_remove(&subsurface->destroy.link);
|
||||
wl_list_remove(&subsurface->commit.link);
|
||||
wl_list_remove(&subsurface->layer_surface_destroy.link);
|
||||
free(subsurface);
|
||||
}
|
||||
|
||||
static struct sway_layer_subsurface *create_subsurface(
|
||||
struct wlr_subsurface *wlr_subsurface,
|
||||
struct sway_layer_surface *layer_surface) {
|
||||
sway_log(SWAY_DEBUG, "new layer subsurface");
|
||||
struct sway_layer_subsurface *subsurface =
|
||||
calloc(1, sizeof(struct sway_layer_surface));
|
||||
if (subsurface == NULL) {
|
||||
|
|
@ -446,6 +458,11 @@ static struct sway_layer_subsurface *create_subsurface(
|
|||
subsurface->commit.notify = subsurface_handle_commit;
|
||||
wl_signal_add(&wlr_subsurface->surface->events.commit, &subsurface->commit);
|
||||
|
||||
subsurface->layer_surface_destroy.notify =
|
||||
subsurface_handle_layer_surface_destroy;
|
||||
wl_signal_add(&layer_surface->layer_surface->events.destroy,
|
||||
&subsurface->layer_surface_destroy);
|
||||
|
||||
return subsurface;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue