From 29cc526e2eab65d856d1fd0a652f22dcdb5d72dd Mon Sep 17 00:00:00 2001 From: Iain Lane Date: Fri, 10 Aug 2018 10:46:51 +0100 Subject: [PATCH] gpu-kms: Handle drmModeGetResources() failing Avoid dereferencing the NULL return value if it fails. We still create the MetaGpu, but we treat it as if it has no outputs. Closes: https://gitlab.gnome.org/GNOME/mutter/issues/223 --- src/backends/native/meta-gpu-kms.c | 36 +++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/src/backends/native/meta-gpu-kms.c b/src/backends/native/meta-gpu-kms.c index 4be5d8550..20e927893 100644 --- a/src/backends/native/meta-gpu-kms.c +++ b/src/backends/native/meta-gpu-kms.c @@ -68,6 +68,8 @@ struct _MetaGpuKms int max_buffer_height; gboolean page_flips_not_supported; + + gboolean resources_init_failed_before; }; G_DEFINE_TYPE (MetaGpuKms, meta_gpu_kms, META_TYPE_GPU) @@ -726,20 +728,34 @@ init_outputs (MetaGpuKms *gpu_kms, setup_output_clones (gpu); } -static void -meta_kms_resources_init (MetaKmsResources *resources, - int fd) +static gboolean +meta_kms_resources_init (MetaKmsResources *resources, + int fd, + GError **error) + { drmModeRes *drm_resources; unsigned int i; drm_resources = drmModeGetResources (fd); + + if (!drm_resources) + { + g_set_error (error, + G_IO_ERROR, + G_IO_ERROR_FAILED, + "Calling drmModeGetResources() failed"); + return FALSE; + } + resources->resources = drm_resources; resources->n_encoders = (unsigned int) drm_resources->count_encoders; resources->encoders = g_new (drmModeEncoder *, resources->n_encoders); for (i = 0; i < resources->n_encoders; i++) resources->encoders[i] = drmModeGetEncoder (fd, drm_resources->encoders[i]); + + return TRUE; } static void @@ -751,7 +767,7 @@ meta_kms_resources_release (MetaKmsResources *resources) drmModeFreeEncoder (resources->encoders[i]); g_free (resources->encoders); - drmModeFreeResources (resources->resources); + g_clear_pointer (&resources->resources, drmModeFreeResources); } static gboolean @@ -762,8 +778,18 @@ meta_gpu_kms_read_current (MetaGpu *gpu, MetaMonitorManager *monitor_manager = meta_gpu_get_monitor_manager (gpu); MetaKmsResources resources; + g_autoptr (GError) local_error = NULL; - meta_kms_resources_init (&resources, gpu_kms->fd); + if (!meta_kms_resources_init (&resources, gpu_kms->fd, &local_error)) + { + if (!gpu_kms->resources_init_failed_before) + { + g_warning ("meta_kms_resources_init failed: %s, assuming we have no outputs", + local_error->message); + gpu_kms->resources_init_failed_before = TRUE; + } + return TRUE; + } gpu_kms->max_buffer_width = resources.resources->max_width; gpu_kms->max_buffer_height = resources.resources->max_height;