libweston, desktop-shell: Add a wrapper for weston_surface reference

Similar to how we do it with drm_fb ref counts, increase a reference
count and return the same object.

Plug-in in desktop-shell when we map up the view in order to survive a
weston_surface destruction.

Astute readers will notice that this patch removes weston_view_destroy()
while keeping the balance between removing and adding a
weston_surface_unref() call in desktop_shell_destroy_surface().

The reason is to let weston_surface_unref() handle destruction on its
own. If multiple references are taken, then weston_surface_unref()
doesn't destroy the view, it just decreases the reference, with
a latter call to weston_surface_unref() to determine if the view
should be destroyed as well.  This situation happens if we have
close animation enabled, were we have more than one reference taken: one
when mapping the view/surface and when when the surface itself was created,
(what we call, a weak reference).

If only a single reference is taken (for instance if we don't have close
animations enabled) then this weston_surface_unref()
call is inert as that reference is not set-up, leaving libweston to
handle the view destruction.

Following that with a weston_view_destroy() explicit call would cause a
UAF as the view was previous destroyed by a weston_surface_unref() call.

A side-effect of not keeping the weston_view_destroy() call would
happen when tearing down the compositor. If close animations are enabled,
weston_surface_unref() would not destroy the view, and because
weston_view_destroy() no longer exists, we would still have the
view in the other layers by the time we check-up if layers
have views present.

Signed-off-by: Marius Vlad <marius.vlad@collabora.com>
This commit is contained in:
Marius Vlad
2022-02-14 22:42:22 +02:00
parent d3ed2eb345
commit bd8314078d
3 changed files with 19 additions and 4 deletions
+10
View File
@@ -2295,6 +2295,16 @@ weston_view_destroy(struct weston_view *view)
free(view);
}
WL_EXPORT struct weston_surface *
weston_surface_ref(struct weston_surface *surface)
{
assert(surface->ref_count < INT32_MAX &&
surface->ref_count > 0);
surface->ref_count++;
return surface;
}
WL_EXPORT void
weston_surface_unref(struct weston_surface *surface)
{