xserver: Branch 'master'

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Sun Dec 17 17:27:28 UTC 2023


 hw/xfree86/fbdevhw/fbdevhw.c |   44 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 43 insertions(+), 1 deletion(-)

New commits:
commit a8e41a81909ef74faa38ef12ca35c5d83f7c56a5
Author: Moritz Bruder <muesli4 at gmail.com>
Date:   Sat Dec 17 18:19:57 2022 +0100

    fbdevhw: Support symbolic links in fbdev_open
    
    Resolve symbolic links before the PCI device check in fbdev_open.
    Otherwise, opening device files that are symbolic links will fail.
    
    Fixes: https://gitlab.freedesktop.org/xorg/xserver/-/issues/1419
    
    Signed-off-by: Moritz Bruder <muesli4 at gmail.com>

diff --git a/hw/xfree86/fbdevhw/fbdevhw.c b/hw/xfree86/fbdevhw/fbdevhw.c
index 3d8b92e66..8d4e3c596 100644
--- a/hw/xfree86/fbdevhw/fbdevhw.c
+++ b/hw/xfree86/fbdevhw/fbdevhw.c
@@ -304,6 +304,31 @@ fbdev_open_pci(struct pci_device *pPci, char **namep)
     return -1;
 }
 
+/* *
+ * Try to resolve a filename as symbolic link.  If the file is not a link, the
+ * original filename is returned.  NULL is returned if readlink raised an
+ * error.
+ */
+static const char *
+resolve_link(const char *filename, char *resolve_buf, size_t resolve_buf_size)
+{
+    ssize_t len = readlink(filename, resolve_buf, resolve_buf_size - 1);
+    /* if it is a link resolve it */
+    if (len >= 0) {
+        resolve_buf[len] = '\0';
+        return resolve_buf;
+    }
+    else {
+        if (errno == EINVAL) {
+            return filename;
+        }
+        else {
+            // Have caller handle error condition.
+            return NULL;
+        }
+    }
+}
+
 static int
 fbdev_open(int scrnIndex, const char *dev, char **namep)
 {
@@ -331,9 +356,26 @@ fbdev_open(int scrnIndex, const char *dev, char **namep)
 
     /* only touch non-PCI devices on this path */
     {
+        char device_path_buf[PATH_MAX];
         char buf[PATH_MAX] = {0};
         char *sysfs_path = NULL;
-        char *node = strrchr(dev, '/') + 1;
+        char const *real_dev = resolve_link(dev, device_path_buf,
+                                            sizeof(device_path_buf));
+        if (real_dev == NULL) {
+            xf86DrvMsg(scrnIndex, X_ERROR,
+                       "Failed resolving symbolic link for device '%s': %s",
+                       dev, strerror(errno));
+            return -1;
+        }
+
+        const char *node = strrchr(real_dev, '/');
+
+        if (node == NULL) {
+            node = real_dev;
+        }
+        else {
+            node++;
+        }
 
         if (asprintf(&sysfs_path, "/sys/class/graphics/%s", node) < 0 ||
             readlink(sysfs_path, buf, sizeof(buf) - 1) < 0 ||


More information about the xorg-commit mailing list