drm: Reset associated universal plane states when finalizing a crtc

When dissociating a universal plane from a crtc, we currently don't
reset the current state of the plane (plane->state_cur). When attempting
to use this plane in the future, we can run into invalid memory accesses
due to left over associations with potentially freed drm backend
objects. This commit resets the state of the scanout and cursor
universal planes associated with a crtc.

The following scenario exhibits the problem:

1. Start a (fullscreen) client that is suitable for and assigned to
   the scanout plane. The plane's state_cur->output value is set.
2. Unplug the monitor: the scanout plane is "released" but still
   maintains the state_cur->output association.
3. Replug the monitor: the plane is deemed unavailable due to an
   existing, albeit invalid, state_cur->output value. Note the memory
   errors trying to access the drm_output which was freed at step (2).

Signed-off-by: Alexandros Frantzis <alexandros.frantzis@collabora.com>
dev
Alexandros Frantzis 4 years ago committed by Daniel Stone
parent 9975134593
commit 53a71cb186
  1. 40
      libweston/backend-drm/drm.c

@ -1679,23 +1679,29 @@ drm_output_fini_crtc(struct drm_output *output)
struct drm_backend *b = to_drm_backend(output->base.compositor); struct drm_backend *b = to_drm_backend(output->base.compositor);
uint32_t *unused; uint32_t *unused;
if (!b->universal_planes && !b->shutting_down) { /* If the compositor is already shutting down, the planes have already
/* With universal planes, the 'special' planes are allocated at * been destroyed. */
* startup, freed at shutdown, and live on the plane list in if (!b->shutting_down) {
* between. We want the planes to continue to exist and be freed if (!b->universal_planes) {
* up for other outputs. /* Without universal planes, our special planes are
* * pseudo-planes allocated at output creation, freed at
* Without universal planes, our special planes are * output destruction, and not usable by other outputs.
* pseudo-planes allocated at output creation, freed at output */
* destruction, and not usable by other outputs. if (output->cursor_plane)
* drm_plane_destroy(output->cursor_plane);
* On the other hand, if the compositor is already shutting down, if (output->scanout_plane)
* the plane has already been destroyed. drm_plane_destroy(output->scanout_plane);
*/ } else {
if (output->cursor_plane) /* With universal planes, the 'special' planes are
drm_plane_destroy(output->cursor_plane); * allocated at startup, freed at shutdown, and live on
if (output->scanout_plane) * the plane list in between. We want the planes to
drm_plane_destroy(output->scanout_plane); * continue to exist and be freed up for other outputs.
*/
if (output->cursor_plane)
drm_plane_reset_state(output->cursor_plane);
if (output->scanout_plane)
drm_plane_reset_state(output->scanout_plane);
}
} }
drm_property_info_free(output->props_crtc, WDRM_CRTC__COUNT); drm_property_info_free(output->props_crtc, WDRM_CRTC__COUNT);

Loading…
Cancel
Save