mirror of
https://gitlab.freedesktop.org/wayland/weston.git
synced 2026-05-08 17:09:41 +02:00
backend-drm: Fix double-free of pending state in error path
drm_pending_state_apply_atomic is supposed to leave pending_state untouched if called as a test-only and that test fails, as per the docs for drm_pending_state_test. If it gets as far as doing the atomic test and it fails, it doesn't free pending_state. However if it fails to even compile the state for the atomic test (for example, if a particular property is not implemented in the driver for a particular plane), it frees pending_state. In this case, drm_output_propose_state will free the contained drm_output_state again, typically leading to a segfault. Treat failing to compile the state for the atomic test in the same way as successfully running the atomic test but it failing. Signed-off-by: Ray Smith <rsmith@brightsign.biz>
This commit is contained in:
parent
847952b711
commit
930f768bdb
1 changed files with 10 additions and 8 deletions
|
|
@ -1625,7 +1625,10 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||
|
||||
if (ret != 0) {
|
||||
weston_log("atomic: couldn't compile atomic state\n");
|
||||
goto out;
|
||||
if (mode == DRM_STATE_TEST_ONLY)
|
||||
goto out_test_only;
|
||||
else
|
||||
goto out;
|
||||
}
|
||||
if (may_tear)
|
||||
tear_flag = DRM_MODE_PAGE_FLIP_ASYNC;
|
||||
|
|
@ -1643,12 +1646,8 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||
if (ret == 0)
|
||||
drm_pending_state_clear_tearing(pending_state);
|
||||
}
|
||||
/* Test commits do not take ownership of the state; return
|
||||
* without freeing here. */
|
||||
if (mode == DRM_STATE_TEST_ONLY) {
|
||||
drmModeAtomicFree(req);
|
||||
return ret;
|
||||
}
|
||||
if (mode == DRM_STATE_TEST_ONLY)
|
||||
goto out_test_only;
|
||||
|
||||
if (ret != 0) {
|
||||
wl_list_for_each(output_state, &pending_state->output_list, link)
|
||||
|
|
@ -1669,8 +1668,11 @@ drm_pending_state_apply_atomic(struct drm_pending_state *pending_state,
|
|||
assert(wl_list_empty(&pending_state->output_list));
|
||||
|
||||
out:
|
||||
drmModeAtomicFree(req);
|
||||
drm_pending_state_free(pending_state);
|
||||
/* Test commits do not take ownership of the state; return
|
||||
* without freeing here. */
|
||||
out_test_only:
|
||||
drmModeAtomicFree(req);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue