From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
From: Jocelyn Falempe <jfalempe@redhat.com>
Date: Thu, 14 Apr 2022 14:39:37 +0200
Subject: [PATCH] Refuse to run if framebuffer or dri devices are present

The simpledrm driver, introduced in kernel 5.14,
can replace efifb to provide the efi framebuffer.

This fixes a bug on Fedora 36 (first version to use simpledrm driver):
https://bugzilla.redhat.com/show_bug.cgi?id=2074789

v2: check for framebuffer or dri devices instead of efi framebuffer interface.

Reviewed-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Javier Martinez Canillas <javierm@redhat.com>
Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 src/vesa.c | 39 ++++++++++++++++++++++++++++++++++-----
 1 file changed, 34 insertions(+), 5 deletions(-)

diff --git a/src/vesa.c b/src/vesa.c
index b2a1922c2332..2bf18e9f278c 100644
--- a/src/vesa.c
+++ b/src/vesa.c
@@ -44,6 +44,7 @@
 
 #include <string.h>
 #include <unistd.h>
+#include <dirent.h>
 #include "vesa.h"
 
 /* All drivers initialising the SW cursor need this */
@@ -439,22 +440,50 @@ VESAInitScrn(ScrnInfoPtr pScrn)
     pScrn->FreeScreen    = VESAFreeScreen;
 }
 
+#ifdef XSERVER_LIBPCIACCESS
+#ifdef __linux__
+/*
+ * check if a file exist in directory
+ * should be equivalent to a glob ${directory}/${prefix}*
+ */
+
+static Bool
+VESAFileExistsPrefix(const char *directory, const char *prefix) {
+    DIR *dir;
+    struct dirent *entry;
+    Bool found = FALSE;
+    int len = strlen(prefix);
+
+    dir = opendir(directory);
+    if (!dir)
+        return FALSE;
+
+    while ((entry = readdir(dir)) != NULL) {
+            if (strlen(entry->d_name) > len &&
+                !memcmp(entry->d_name, prefix, len)) {
+                found = TRUE;
+                break;
+            }
+        }
+    closedir(dir);
+    return found;
+}
+#endif
+
 /*
  * This function is called once, at the start of the first server generation to
  * do a minimal probe for supported hardware.
  */
-
-#ifdef XSERVER_LIBPCIACCESS
 static Bool
 VESAPciProbe(DriverPtr drv, int entity_num, struct pci_device *dev,
 	     intptr_t match_data)
 {
     ScrnInfoPtr pScrn;
 
 #ifdef __linux__
-    if (access("/sys/devices/platform/efi-framebuffer.0", F_OK) == 0 ||
-        access("/sys/devices/platform/efifb.0", F_OK) == 0) {
-        ErrorF("vesa: Refusing to run on UEFI\n");
+    if (VESAFileExistsPrefix("/dev", "fb") ||
+        VESAFileExistsPrefix("/dev/dri", "card")) {
+        ErrorF("vesa: Refusing to run, Framebuffer or dri device present\n");
         return FALSE;
     }
 #endif
