[at-spi2-core] Bus launcher: place a11y bus socket in the user's working directory



commit 412bdee0a1daa3fe9bc7d1fa289a31495dff3387
Author: Mike Gorse <mgorse suse com>
Date:   Wed Dec 8 16:02:10 2021 -0600

    Bus launcher: place a11y bus socket in the user's working directory
    
    The old behavior of using /tmp broke accessibility for Snap-confined
    applications, since Snap provides a private version of /tmp.
    Also stop using abstract sockets for dbus-broker, except that we fall back
    to the old behavior in the unlikely event that the user's working
    directory can't be determined.
    
    Fixes #43

 bus/at-spi-bus-launcher.c | 45 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 40 insertions(+), 5 deletions(-)
---
diff --git a/bus/at-spi-bus-launcher.c b/bus/at-spi-bus-launcher.c
index ddbae15e..b0ccab67 100644
--- a/bus/at-spi-bus-launcher.c
+++ b/bus/at-spi-bus-launcher.c
@@ -42,6 +42,7 @@
 #ifdef DBUS_BROKER
 #include <systemd/sd-login.h>
 #endif
+#include <sys/stat.h>
 
 typedef enum {
   A11Y_BUS_STATE_IDLE = 0,
@@ -65,6 +66,7 @@ typedef struct {
   A11yBusState state;
   /* -1 == error, 0 == pending, > 0 == running */
   int a11y_bus_pid;
+  char *socket_name;
   char *a11y_bus_address;
 #ifdef HAVE_X11
   gboolean x11_prop_set;
@@ -306,7 +308,7 @@ setup_bus_child_daemon (gpointer data)
 static gboolean
 ensure_a11y_bus_daemon (A11yBusLauncher *app, char *config_path)
 {
-  char *argv[] = { DBUS_DAEMON, config_path, "--nofork", "--print-address", "3", NULL };
+  char *argv[] = { DBUS_DAEMON, config_path, "--nofork", "--print-address", "3", NULL, NULL };
   GPid pid;
   char addr_buf[2048];
   GError *error = NULL;
@@ -316,6 +318,9 @@ ensure_a11y_bus_daemon (A11yBusLauncher *app, char *config_path)
 
   g_clear_pointer (&app->a11y_launch_error_message, g_free);
 
+  if (app->socket_name)
+    argv[5] = g_strconcat ("--address=unix:path=", app->socket_name, NULL);
+
   if (!g_spawn_async (NULL,
                       argv,
                       NULL,
@@ -328,9 +333,11 @@ ensure_a11y_bus_daemon (A11yBusLauncher *app, char *config_path)
       app->a11y_bus_pid = -1;
       app->a11y_launch_error_message = g_strdup (error->message);
       g_clear_error (&error);
+      g_free (argv[5]);
       goto error;
     }
 
+  g_free (argv[5]);
   close (app->pipefd[1]);
   app->pipefd[1] = -1;
 
@@ -396,11 +403,14 @@ ensure_a11y_bus_broker (A11yBusLauncher *app, char *config_path)
 {
   char *argv[] = { DBUS_BROKER, config_path, "--scope", "user", NULL };
   char *unit;
-  struct sockaddr_un addr = { .sun_family = AF_UNIX };
+  struct sockaddr_un addr = { .sun_family = AF_UNIX, '\0' };
   socklen_t addr_len = sizeof(addr);
   GPid pid;
   GError *error = NULL;
 
+  if (app->socket_name)
+    strcpy (addr.sun_path, app->socket_name);
+
   /* This detects whether we are running under systemd. We only try to
    * use dbus-broker if we are running under systemd because D-Bus
    * service activation won't work otherwise.
@@ -418,10 +428,11 @@ ensure_a11y_bus_broker (A11yBusLauncher *app, char *config_path)
   if ((app->listenfd = socket (PF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0)) < 0)
     g_error ("Failed to create listening socket: %s", strerror (errno));
 
-  if (bind (app->listenfd, (struct sockaddr *)&addr, sizeof(sa_family_t)) < 0)
+  if (bind (app->listenfd, (struct sockaddr *)&addr, addr_len) < 0)
     g_error ("Failed to bind listening socket: %s", strerror (errno));
 
-  if (getsockname (app->listenfd, (struct sockaddr *)&addr, &addr_len) < 0)
+  if (!app->socket_name &&
+      getsockname (app->listenfd, (struct sockaddr *)&addr, &addr_len) < 0)
     g_error ("Failed to get socket name for listening socket: %s", strerror(errno));
 
   if (listen (app->listenfd, 1024) < 0)
@@ -452,7 +463,10 @@ ensure_a11y_bus_broker (A11yBusLauncher *app, char *config_path)
   g_debug ("Launched a11y bus, child is %ld", (long) pid);
   app->state = A11Y_BUS_STATE_RUNNING;
 
-  app->a11y_bus_address = g_strconcat("unix:abstract=", addr.sun_path + 1, NULL);
+  if (app->socket_name)
+    app->a11y_bus_address = g_strconcat("unix:path=", addr.sun_path, NULL);
+  else
+    app->a11y_bus_address = g_strconcat("unix:abstract=", addr.sun_path + 1, NULL);
   g_debug ("a11y bus address: %s", app->a11y_bus_address);
 
   return TRUE;
@@ -476,6 +490,7 @@ ensure_a11y_bus (A11yBusLauncher *app)
 {
   char *config_path = NULL;
   gboolean success = FALSE;
+  const gchar *xdg_runtime_dir;
 
   if (app->a11y_bus_pid != 0)
     return FALSE;
@@ -485,6 +500,26 @@ ensure_a11y_bus (A11yBusLauncher *app)
   else
       config_path = "--config-file="DATADIR"/defaults/at-spi2/accessibility.conf";
 
+    xdg_runtime_dir = g_get_user_runtime_dir ();
+    if (xdg_runtime_dir)
+      {
+        const gchar *display = g_getenv ("DISPLAY");
+        gchar *at_spi_dir = g_strconcat (xdg_runtime_dir, "/at-spi", NULL);
+        gchar *p;
+        mkdir (at_spi_dir, 0700);
+        app->socket_name = g_strconcat (at_spi_dir, "/bus", display, NULL);
+        g_free (at_spi_dir);
+        p = strchr (app->socket_name, ':');
+        if (p)
+          *p = '_';
+        if (strlen (app->socket_name) >= 100)
+          {
+            g_free (app->socket_name);
+            g_free (at_spi_dir);
+            app->socket_name = NULL;
+          }
+      }
+
 #ifdef WANT_DBUS_BROKER
     success = ensure_a11y_bus_broker (app, config_path);
     if (!success)


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