mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-12-02 06:47:13 +01:00
gdbusserver: retry binding to unix addresses only when possible
This adds the condition that a new unix address is tried only when there is enough space to append random character(s) before the address reach the length of UNIX_PATH_MAX. Before this change, creating a GDBusServer with unix addresses longer than UNIX_PATH_MAX that existed in the filesystem would never return. A test that expects G_IO_ERROR_ADDRESS_IN_USE in such scenario was added.
This commit is contained in:
@@ -45,12 +45,14 @@
|
|||||||
#include "ginputstream.h"
|
#include "ginputstream.h"
|
||||||
#include "giostream.h"
|
#include "giostream.h"
|
||||||
#include "gmarshal-internal.h"
|
#include "gmarshal-internal.h"
|
||||||
|
#include "gnetworking.h"
|
||||||
|
|
||||||
#ifdef G_OS_UNIX
|
#ifdef G_OS_UNIX
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#ifdef G_OS_WIN32
|
#ifdef G_OS_WIN32
|
||||||
#include <io.h>
|
#include <io.h>
|
||||||
|
#include "giowin32-afunix.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "gunixsocketaddress.h"
|
#include "gunixsocketaddress.h"
|
||||||
@@ -62,6 +64,10 @@
|
|||||||
G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS | \
|
G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS | \
|
||||||
G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER)
|
G_DBUS_SERVER_FLAGS_AUTHENTICATION_REQUIRE_SAME_USER)
|
||||||
|
|
||||||
|
#ifndef UNIX_PATH_MAX
|
||||||
|
#define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path)
|
||||||
|
#endif
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* GDBusServer:
|
* GDBusServer:
|
||||||
*
|
*
|
||||||
@@ -699,10 +705,12 @@ try_unix (GDBusServer *server,
|
|||||||
gint n;
|
gint n;
|
||||||
GString *s;
|
GString *s;
|
||||||
GError *local_error;
|
GError *local_error;
|
||||||
|
gsize orig_path_len = 0; // length before random characters are added
|
||||||
|
|
||||||
retry:
|
retry:
|
||||||
s = g_string_new (tmpdir != NULL ? tmpdir : dir);
|
s = g_string_new (tmpdir != NULL ? tmpdir : dir);
|
||||||
g_string_append (s, "/dbus-");
|
g_string_append (s, "/dbus-");
|
||||||
|
orig_path_len = s->len;
|
||||||
for (n = 0; n < 8; n++)
|
for (n = 0; n < 8; n++)
|
||||||
g_string_append_c (s, random_ascii ());
|
g_string_append_c (s, random_ascii ());
|
||||||
|
|
||||||
@@ -720,8 +728,11 @@ try_unix (GDBusServer *server,
|
|||||||
{
|
{
|
||||||
if (local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_ADDRESS_IN_USE)
|
if (local_error->domain == G_IO_ERROR && local_error->code == G_IO_ERROR_ADDRESS_IN_USE)
|
||||||
{
|
{
|
||||||
g_error_free (local_error);
|
if (orig_path_len < UNIX_PATH_MAX - 2) /* random_ascii + NULL byte */
|
||||||
goto retry;
|
{
|
||||||
|
g_error_free (local_error);
|
||||||
|
goto retry;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g_propagate_error (error, local_error);
|
g_propagate_error (error, local_error);
|
||||||
goto out;
|
goto out;
|
||||||
|
|||||||
@@ -537,6 +537,50 @@ test_server_auth_sha1_tcp (void)
|
|||||||
do_test_server_auth (INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP);
|
do_test_server_auth (INTEROP_FLAGS_SHA1 | INTEROP_FLAGS_TCP);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_server_path_in_use (void)
|
||||||
|
{
|
||||||
|
#ifdef G_OS_UNIX
|
||||||
|
#ifndef UNIX_PATH_MAX
|
||||||
|
#define UNIX_PATH_MAX G_SIZEOF_MEMBER (struct sockaddr_un, sun_path)
|
||||||
|
#endif
|
||||||
|
GError *error = NULL;
|
||||||
|
GString *path = NULL;
|
||||||
|
gchar *listenable_address = NULL;
|
||||||
|
GDBusServer *server = NULL;
|
||||||
|
gchar *guid = NULL;
|
||||||
|
gchar *escaped = NULL;
|
||||||
|
|
||||||
|
path = g_string_new (g_get_tmp_dir ());
|
||||||
|
guid = g_dbus_generate_guid ();
|
||||||
|
while (path->len < UNIX_PATH_MAX - 1)
|
||||||
|
g_string_append_c (path, 'x');
|
||||||
|
escaped = g_dbus_address_escape_value (path->str);
|
||||||
|
listenable_address = g_strdup_printf ("unix:%s=%s", "dir", escaped);
|
||||||
|
g_assert_cmpint (g_mkdir_with_parents (path->str, 0700), ==, 0);
|
||||||
|
g_string_free (path, TRUE);
|
||||||
|
|
||||||
|
server = g_dbus_server_new_sync (listenable_address,
|
||||||
|
G_DBUS_SERVER_FLAGS_RUN_IN_THREAD,
|
||||||
|
guid,
|
||||||
|
NULL,
|
||||||
|
NULL,
|
||||||
|
&error);
|
||||||
|
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE);
|
||||||
|
g_error_free (error);
|
||||||
|
|
||||||
|
if (server != NULL)
|
||||||
|
g_dbus_server_stop (server);
|
||||||
|
|
||||||
|
g_clear_object (&server);
|
||||||
|
g_free (guid);
|
||||||
|
g_free (escaped);
|
||||||
|
g_free (listenable_address);
|
||||||
|
#else
|
||||||
|
g_test_skip ("unix: addresses only work on Unix");
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
main (int argc,
|
main (int argc,
|
||||||
char *argv[])
|
char *argv[])
|
||||||
@@ -552,6 +596,7 @@ main (int argc,
|
|||||||
g_test_add_func ("/gdbus/server-auth/external/require-same-user", test_server_auth_external_require_same_user);
|
g_test_add_func ("/gdbus/server-auth/external/require-same-user", test_server_auth_external_require_same_user);
|
||||||
g_test_add_func ("/gdbus/server-auth/sha1", test_server_auth_sha1);
|
g_test_add_func ("/gdbus/server-auth/sha1", test_server_auth_sha1);
|
||||||
g_test_add_func ("/gdbus/server-auth/sha1/tcp", test_server_auth_sha1_tcp);
|
g_test_add_func ("/gdbus/server-auth/sha1/tcp", test_server_auth_sha1_tcp);
|
||||||
|
g_test_add_func ("/gdbus/server-auth/path-in-use", test_server_path_in_use);
|
||||||
|
|
||||||
return g_test_run();
|
return g_test_run();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user