mirror of
https://github.com/mpv-player/mpv
synced 2025-02-16 20:27:23 +00:00
context_drm_egl: check for non-existant drm in uninit
Previously, if vo_drm_init failed at the start of drm_egl_init it caused a use-after-free in drm_egl_uninit when it tried to access the non-existant drm context. At that point vo_drm_uninit had already been called resulting in two different null pointer dereference. In this situation the DRM private context had also not been allocated.
This commit is contained in:
parent
2a2cb6a49e
commit
a1a2e27f84
@ -475,33 +475,38 @@ static void drm_egl_uninit(struct ra_ctx *ctx)
|
||||
{
|
||||
struct priv *p = ctx->priv;
|
||||
struct vo_drm_state *drm = ctx->vo->drm;
|
||||
struct drm_atomic_context *atomic_ctx = drm->atomic_context;
|
||||
if (drm) {
|
||||
struct drm_atomic_context *atomic_ctx = drm->atomic_context;
|
||||
|
||||
if (drmModeAtomicCommit(drm->fd, atomic_ctx->request, 0, NULL))
|
||||
MP_ERR(ctx->vo, "Failed to commit atomic request: %s\n", mp_strerror(errno));
|
||||
if (drmModeAtomicCommit(drm->fd, atomic_ctx->request, 0, NULL))
|
||||
MP_ERR(ctx->vo, "Failed to commit atomic request: %s\n",
|
||||
mp_strerror(errno));
|
||||
|
||||
drmModeAtomicFree(atomic_ctx->request);
|
||||
drmModeAtomicFree(atomic_ctx->request);
|
||||
}
|
||||
|
||||
vo_drm_uninit(ctx->vo);
|
||||
ra_gl_ctx_uninit(ctx);
|
||||
|
||||
// According to GBM documentation all BO:s must be released before
|
||||
// gbm_surface_destroy can be called on the surface.
|
||||
while (p->gbm.num_bos) {
|
||||
swapchain_step(ctx);
|
||||
if (p) {
|
||||
// According to GBM documentation all BO:s must be released
|
||||
// before gbm_surface_destroy can be called on the surface.
|
||||
while (p->gbm.num_bos) {
|
||||
swapchain_step(ctx);
|
||||
}
|
||||
|
||||
eglMakeCurrent(p->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
eglDestroyContext(p->egl.display, p->egl.context);
|
||||
eglDestroySurface(p->egl.display, p->egl.surface);
|
||||
gbm_surface_destroy(p->gbm.surface);
|
||||
eglTerminate(p->egl.display);
|
||||
gbm_device_destroy(p->gbm.device);
|
||||
p->egl.context = EGL_NO_CONTEXT;
|
||||
eglDestroyContext(p->egl.display, p->egl.context);
|
||||
|
||||
close(p->drm_params.render_fd);
|
||||
}
|
||||
|
||||
eglMakeCurrent(p->egl.display, EGL_NO_SURFACE, EGL_NO_SURFACE,
|
||||
EGL_NO_CONTEXT);
|
||||
eglDestroyContext(p->egl.display, p->egl.context);
|
||||
eglDestroySurface(p->egl.display, p->egl.surface);
|
||||
gbm_surface_destroy(p->gbm.surface);
|
||||
eglTerminate(p->egl.display);
|
||||
gbm_device_destroy(p->gbm.device);
|
||||
p->egl.context = EGL_NO_CONTEXT;
|
||||
eglDestroyContext(p->egl.display, p->egl.context);
|
||||
|
||||
close(p->drm_params.render_fd);
|
||||
}
|
||||
|
||||
// If the draw plane supports ARGB we want to use that, but if it doesn't we
|
||||
|
Loading…
Reference in New Issue
Block a user