Blob Blame History Raw
From 255146e4a3d16c74390f8fdd6cae46b5d0d59ad5 Mon Sep 17 00:00:00 2001
From: Iain Lane <iainl@gnome.org>
Date: Fri, 10 Aug 2018 09:46:51 +0000
Subject: [PATCH 1/2] 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


(cherry picked from commit 29cc526e2eab65d856d1fd0a652f22dcdb5d72dd)
---
 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 1d1c28809..7e7607c46 100644
--- a/src/backends/native/meta-gpu-kms.c
+++ b/src/backends/native/meta-gpu-kms.c
@@ -62,6 +62,8 @@ struct _MetaGpuKms
   int max_buffer_height;
 
   gboolean page_flips_not_supported;
+
+  gboolean resources_init_failed_before;
 };
 
 G_DEFINE_QUARK (MetaGpuKmsError, meta_gpu_kms_error)
@@ -709,20 +711,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
@@ -734,7 +750,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
@@ -745,8 +761,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;
-- 
2.19.0