diff options
author | Matthew Lindner <mattlindn@gmail.com> | 2023-03-29 11:31:08 -0700 |
---|---|---|
committer | Dudemanguy <random342@airmail.cc> | 2023-05-22 21:47:24 -0500 |
commit | a1a2e27f84bef17b50fd7f5cca7e50bbad1f92d0 (patch) | |
tree | 8e164584c4954f8800999f37a17acbf72e1600e4 /video/out | |
parent | 2a2cb6a49eb0616d04a8d707513affd687e00a32 (diff) | |
download | mpv-a1a2e27f84bef17b50fd7f5cca7e50bbad1f92d0.tar.bz2 mpv-a1a2e27f84bef17b50fd7f5cca7e50bbad1f92d0.tar.xz |
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.
Diffstat (limited to 'video/out')
-rw-r--r-- | video/out/opengl/context_drm_egl.c | 43 |
1 files changed, 24 insertions, 19 deletions
diff --git a/video/out/opengl/context_drm_egl.c b/video/out/opengl/context_drm_egl.c index 79ef10f2f6..abd3e99c3b 100644 --- a/video/out/opengl/context_drm_egl.c +++ b/video/out/opengl/context_drm_egl.c @@ -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); + 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); + close(p->drm_params.render_fd); + } } // If the draw plane supports ARGB we want to use that, but if it doesn't we |