summaryrefslogtreecommitdiffstats
path: root/video
diff options
context:
space:
mode:
authorMatthew Lindner <mattlindn@gmail.com>2023-03-29 11:31:08 -0700
committerDudemanguy <random342@airmail.cc>2023-05-22 21:47:24 -0500
commita1a2e27f84bef17b50fd7f5cca7e50bbad1f92d0 (patch)
tree8e164584c4954f8800999f37a17acbf72e1600e4 /video
parent2a2cb6a49eb0616d04a8d707513affd687e00a32 (diff)
downloadmpv-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')
-rw-r--r--video/out/opengl/context_drm_egl.c43
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