From b9c21e5872108c5f8d9fbfe9f9b1a06e430c030a Mon Sep 17 00:00:00 2001 From: Simon McVittie Date: Tue, 20 Jun 2017 14:37:04 +0100 Subject: [PATCH 06/49] Add unix:dir=/something addresses These are like unix:tmpdir=/something, except that the resulting socket is always path-based, never abstract. This is desirable for two reasons: * If a Linux container manager wants to expose a path-based socket into the container, it can do so by bind-mounting it in the container's filesystem namespace. That cannot work for abstract sockets because they are not files. * Conversely, if a Linux container manager does not want to expose a path-based socket in the container, it can avoid bind-mounting it, or bind-mount some harmless object like /dev/null over it. That cannot work for abstract sockets because access to abstract sockets is part of the network namespace, which is all-or-nothing. Signed-off-by: Simon McVittie --- dbus/dbus-server-unix.c | 32 ++++++++++++++++++++------------ doc/dbus-specification.xml | 38 ++++++++++++++++++++++++++++++++------ 2 files changed, 52 insertions(+), 18 deletions(-) diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c index 92664a8d..fd9348ab 100644 --- a/dbus/dbus-server-unix.c +++ b/dbus/dbus-server-unix.c @@ -64,18 +64,19 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, if (strcmp (method, "unix") == 0) { const char *path = dbus_address_entry_get_value (entry, "path"); + const char *dir = dbus_address_entry_get_value (entry, "dir"); const char *tmpdir = dbus_address_entry_get_value (entry, "tmpdir"); const char *abstract = dbus_address_entry_get_value (entry, "abstract"); const char *runtime = dbus_address_entry_get_value (entry, "runtime"); int mutually_exclusive_modes = 0; mutually_exclusive_modes = (path != NULL) + (tmpdir != NULL) + - (abstract != NULL) + (runtime != NULL); + (abstract != NULL) + (runtime != NULL) + (dir != NULL); if (mutually_exclusive_modes < 1) { _dbus_set_bad_address(error, "unix", - "path or tmpdir or abstract or runtime", + "path or tmpdir or abstract or runtime or dir", NULL); return DBUS_SERVER_LISTEN_BAD_ADDRESS; } @@ -83,7 +84,7 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, if (mutually_exclusive_modes > 1) { _dbus_set_bad_address(error, NULL, NULL, - "cannot specify two of \"path\", \"tmpdir\", \"abstract\" and \"runtime\" at the same time"); + "cannot specify two of \"path\", \"tmpdir\", \"abstract\", \"runtime\" and \"dir\" at the same time"); return DBUS_SERVER_LISTEN_BAD_ADDRESS; } @@ -134,10 +135,23 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, _dbus_string_free (&full_path); } - else if (tmpdir != NULL) + else if (tmpdir != NULL || dir != NULL) { DBusString full_path; DBusString filename; + dbus_bool_t use_abstract = FALSE; + + if (tmpdir != NULL) + { + dir = tmpdir; + +#ifdef HAVE_ABSTRACT_SOCKETS + /* Use abstract sockets for tmpdir if supported, so that it + * never needs to be cleaned up. Use dir instead if you want a + * path-based socket. */ + use_abstract = TRUE; +#endif + } if (!_dbus_string_init (&full_path)) { @@ -167,7 +181,7 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; } - if (!_dbus_string_append (&full_path, tmpdir) || + if (!_dbus_string_append (&full_path, dir) || !_dbus_concat_dir_and_file (&full_path, &filename)) { _dbus_string_free (&full_path); @@ -176,15 +190,9 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; } - /* Always use abstract namespace if possible with tmpdir */ - *server_p = _dbus_server_new_for_domain_socket (_dbus_string_get_const_data (&full_path), -#ifdef HAVE_ABSTRACT_SOCKETS - TRUE, -#else - FALSE, -#endif + use_abstract, error); _dbus_string_free (&full_path); diff --git a/doc/dbus-specification.xml b/doc/dbus-specification.xml index 7013e8bf..5145581c 100644 --- a/doc/dbus-specification.xml +++ b/doc/dbus-specification.xml @@ -3223,7 +3223,8 @@ Unix addresses that specify path or abstract are both listenable and connectable. - Unix addresses that specify tmpdir are only + Unix addresses that specify tmpdir + or dir are only listenable: the corresponding connectable address will specify either path or abstract. Similarly, Unix addresses that specify runtime @@ -3249,17 +3250,42 @@ path (path) - path of the unix domain socket. If set, the "tmpdir" and "abstract" key must not be set. + + Path of the unix domain socket. + + + + dir + (path) + + Directory in which a socket file with a random file name + starting with 'dbus-' will be created by the server. This key + can only be used in server addresses, not in client addresses; + the resulting client address will have the "path" key instead. + be set. + tmpdir (path) - temporary directory in which a socket file with a random file name starting with 'dbus-' will be created by the server. This key can only be used in server addresses, not in client addresses. If set, the "path" and "abstract" key must not be set. + + The same as "dir", except that on platforms with + abstract sockets, the server may attempt to create an + abstract socket whose name starts with this directory instead + of a path-based socket. This key can only be used in server + addresses, not in client addresses; the resulting client address + will have the "abstract" or "path" key instead. + abstract (string) - unique string (path) in the abstract namespace. If set, the "path" or "tmpdir" key must not be set. This key is only supported on platforms with "abstract Unix sockets", of which Linux is the only known example. + + Unique string in the abstract namespace, often syntactically + resembling a path but unconnected to the filesystem namespace. + This key is only supported on platforms with abstract Unix + sockets, of which Linux is the only known example. + runtime @@ -3271,8 +3297,8 @@ Exactly one of the keys path, - abstract, runtime or - tmpdir must be provided. + abstract, runtime, + dir or tmpdir must be provided. -- 2.11.0