[mutter/gnome-3-38] xwayland: Check permissions on /tmp/.X11-unix



commit f51c06d8fd6fbfd033a4cff78b68a35fb7e29cd2
Author: Olivier Fourdan <ofourdan redhat com>
Date:   Thu Mar 18 09:56:34 2021 +0100

    xwayland: Check permissions on /tmp/.X11-unix
    
    For Xwayland, mutter creates the sockets in the standard /tmp/.X11-unix
    directory.
    
    Yet, if that directory already exists, it may have been created by
    another user with full control over the created socket.
    
    To avoid that issue, if the directory /tmp/.X11-unix already exists,
    check that the permissions are as we expect, i.e. the directory belongs
    to either root or the user herself, is writable and has the sticky bit.
    
    Thanks to fabian ritter-vogt de for reporting that issue.
    
    https://gitlab.gnome.org/GNOME/mutter/-/issues/1708
    (cherry picked from commit 3a08fcf2accb4b42fe85f98ddf83223200db928e)
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1788>

 src/wayland/meta-xwayland.c | 45 ++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 44 insertions(+), 1 deletion(-)
---
diff --git a/src/wayland/meta-xwayland.c b/src/wayland/meta-xwayland.c
index 2cffa4b7c5..9cd4a2e6bc 100644
--- a/src/wayland/meta-xwayland.c
+++ b/src/wayland/meta-xwayland.c
@@ -417,13 +417,56 @@ open_display_sockets (MetaXWaylandManager *manager,
   return TRUE;
 }
 
+static gboolean
+ensure_x11_unix_perms (GError **error)
+{
+  struct stat buf;
+
+  if (lstat (X11_TMP_UNIX_DIR, &buf) != 0)
+    {
+      g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
+                   "Failed to check permissions on directory \"%s\": %s",
+                   X11_TMP_UNIX_DIR, g_strerror (errno));
+      return FALSE;
+    }
+
+  /* If the directory already exists, it should belong to root or ourselves ... */
+  if (buf.st_uid != 0 && buf.st_uid != getuid ())
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+                   "Wrong ownership for directory \"%s\"",
+                   X11_TMP_UNIX_DIR);
+      return FALSE;
+    }
+
+  /* ... be writable ... */
+  if ((buf.st_mode & 0022) != 0022)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+                   "Directory \"%s\" is not writable",
+                   X11_TMP_UNIX_DIR);
+      return FALSE;
+    }
+
+  /* ... and have the sticky bit set */
+  if ((buf.st_mode & 01000) != 01000)
+    {
+      g_set_error (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED,
+                   "Directory \"%s\" is missing the sticky bit",
+                   X11_TMP_UNIX_DIR);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
 static gboolean
 ensure_x11_unix_dir (GError **error)
 {
   if (mkdir (X11_TMP_UNIX_DIR, 01777) != 0)
     {
       if (errno == EEXIST)
-        return TRUE;
+        return ensure_x11_unix_perms (error);
 
       g_set_error (error, G_IO_ERROR, g_io_error_from_errno (errno),
                    "Failed to create directory \"%s\": %s",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]