Abstract unix sockets and session socket address

Alexander Larsson <[email protected]>
Newsgroups gmane.comp.freedesktop.dbus
Message-ID <[email protected]>
I'm currently working on a desktop "app" system using container
technologies, and I'm running into an issue with dbus use of abstract
sockets. In the long run I want to do fully sandboxed apps, which
implies kdbus. However, at the moment I want to just use the container
aspect to ease deployment of apps (use a separate runtime for the app
and the host), and as such I want the apps to be able to talk to dbus.

In general, abstract sockets are a bad idea whenever namespaces are
involved. Abstract sockets exist in a global namespace for each network
namespace in use. This means that you can't have an app in its own
network namespace and still talk to the session bus. It also means that
if you're sharing the network namespace with the host there is no way to
disallow the app access to the session bus (or any other service on the
host using abstract sockets).

Regular non-abstract sockets are a much better fit for this. Since they
exist in the regular filesystem tree they are naturally namespaced via
the filesystem namespace, and you can easily "transplant" any particular
socket from one namespace to the other using things like bind mounts. It
also allows filesystem permission checks on the sockets.

In a modern desktop linux the natural place to put the session socket is
in XDG_RUNTIME_DIR, as this is a ephemeral location tied to the user
login. In fact, the cleanup semantics of this directory solves the
cleanup problems that caused dbus to use abstract sockets to begin with.

I'm attaching a patch that lets you specify runtime=yes, or
noabstract=yes in the listen address. With this you can have in your
session.conf:
  <listen>unix:tmpdir=/tmp,runtime=yes</listen>

In fact, I would propose that we make this the new default, as its a
no-op if XDG_RUNTIME_DIR is not set.
0001-Allow-configuring-unix-sockets-in-XDG_RUNTIME_DIR-an.patch (text/x-patch, 3.3 KB)
From b7df05fe0676a97e40b28f87ba0df315ab5ce3f0 Mon Sep 17 00:00:00 2001
From: Alexander Larsson <[email protected]>
Date: Tue, 16 Dec 2014 10:16:24 +0100
Subject: [PATCH] Allow configuring unix sockets in XDG_RUNTIME_DIR and
 non-abstact sockets

This allows you to write unix addresses of the form:
 unix:tmpdir=/tmp,runtime=yes
Which, if XDG_RUNTIME_DIR falls back on using that instead of the
specified tmpdir. Also, in this case it never uses abstract sockets
since that doesn't really make sense.

It also allows specifying noabstract=yes as a modifier for tmpdir in
case you want to avoid abstract sockets automatically being used.  In
some cases abstract sockets are problematic due to global namespace it
uses. For instance, any container that shares the host network
namespace will be able to see all containers abstract sockets, and
for containers that don't share the host network it will be impossible
to access abstract sockets from the host.
---
 dbus/dbus-server-unix.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c
index d995240..c34fb99 100644
--- a/dbus/dbus-server-unix.c
+++ b/dbus/dbus-server-unix.c
@@ -66,6 +66,10 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
       const char *path = dbus_address_entry_get_value (entry, "path");
       const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir");
       const char *abstract = dbus_address_entry_get_value (entry, "abstract");
+      const char *runtime_val = dbus_address_entry_get_value (entry, "runtime");
+      dbus_bool_t runtime = runtime_val != NULL && strcmp (runtime_val, "no") != 0;
+      const char *noabstract_val = dbus_address_entry_get_value (entry, "noabstract");
+      dbus_bool_t noabstract = noabstract_val != NULL && strcmp (noabstract_val, "no") != 0;
 
       if (path == NULL && tmpdir == NULL && abstract == NULL)
         {
@@ -86,9 +90,18 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
 
       if (tmpdir != NULL)
         {
+          const char *runtimedir = NULL;
           DBusString full_path;
           DBusString filename;
 
+          if (runtime)
+            {
+              /* If runtime requested and XDG_RUNTIME_DIR is set, prefer it over tmpdir */
+              runtimedir = _dbus_getenv ("XDG_RUNTIME_DIR");
+              if (runtimedir != NULL)
+                tmpdir = runtimedir;
+            }
+
           if (!_dbus_string_init (&full_path))
             {
               dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
@@ -114,12 +127,13 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry,
               return DBUS_SERVER_LISTEN_DID_NOT_CONNECT;
             }
 
-          /* Always use abstract namespace if possible with tmpdir */
+          /* Always use abstract namespace if possible with tmpdir, unless
+           * it was specifically disabled or we're using XDG_RUNTIME_DIR  */
 
           *server_p =
             _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path),
 #ifdef HAVE_ABSTRACT_SOCKETS
-                                                TRUE,
+                                                (noabstract || runtimedir != NULL) ? FALSE : TRUE,
 #else
                                                 FALSE,
 #endif
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.