diff --git a/NEWS b/NEWS index 3779717f..98dc8586 100644 --- a/NEWS +++ b/NEWS @@ -30,6 +30,23 @@ Enhancements: Fixes: +• Prevent symlink attacks in the nonce-tcp transport on Unix that could + allow an attacker to overwrite a file named "nonce", in a directory + that the user running dbus-daemon can write, with a random value + known only to the user running dbus-daemon. This is unlikely to be + exploitable in practice, particularly since the nonce-tcp transport + is really only useful on Windows. + + On Unix systems we strongly recommend using only the unix: and systemd: + transports, together with EXTERNAL authentication. These are the only + transports and authentication mechanisms enabled by default. + + (fd.o #99828, Simon McVittie) + +• Avoid symlink attacks in the "embedded tests", which are not enabled + by default and should never be enabled in production builds of dbus. + (fd.o #99828, Simon McVittie) + • Fix the implementation of re-enabling a timeout so that its countdown is restarted as intended, instead of continually decreasing. (fd.o #95619; Michal Koutný, Simon McVittie) diff --git a/bus/activation.c b/bus/activation.c index 517af1ec..a104276f 100644 --- a/bus/activation.c +++ b/bus/activation.c @@ -2441,21 +2441,8 @@ out: static dbus_bool_t init_service_reload_test (DBusString *dir) { - DBusStat stat_buf; - - if (!_dbus_stat (dir, &stat_buf, NULL)) - { - if (!_dbus_create_directory (dir, NULL)) - return FALSE; - } - else - { - if (!test_remove_directory (dir)) - return FALSE; - - if (!_dbus_create_directory (dir, NULL)) - return FALSE; - } + if (!_dbus_create_directory (dir, NULL)) + return FALSE; /* Create one initial file */ if (!test_create_service_file (dir, SERVICE_FILE_1, SERVICE_NAME_1, "exec-1")) @@ -2643,6 +2630,9 @@ bus_activation_service_reload_test (const DBusString *test_data_dir) /* Do nothing? */ } + if (!cleanup_service_reload_test (&directory)) + goto out; + /* Do OOM tests */ if (!init_service_reload_test (&directory)) _dbus_assert_not_reached ("could not initiate service reload test"); diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c index 6512a1d5..d9adaa6a 100644 --- a/dbus/dbus-keyring.c +++ b/dbus/dbus-keyring.c @@ -807,7 +807,7 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials, * unless someone else manages to create it */ dbus_error_init (&tmp_error); - if (!_dbus_create_directory (&keyring->directory, + if (!_dbus_ensure_directory (&keyring->directory, &tmp_error)) { _dbus_verbose ("Creating keyring directory: %s\n", diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c index 377e9e27..39c13360 100644 --- a/dbus/dbus-sysdeps-unix.c +++ b/dbus/dbus-sysdeps-unix.c @@ -2955,7 +2955,7 @@ _dbus_get_real_time (long *tv_sec, * @returns #TRUE on success */ dbus_bool_t -_dbus_create_directory (const DBusString *filename, +_dbus_ensure_directory (const DBusString *filename, DBusError *error) { const char *filename_c; @@ -2978,6 +2978,35 @@ _dbus_create_directory (const DBusString *filename, return TRUE; } +/** + * Creates a directory. Unlike _dbus_ensure_directory(), this only succeeds + * if the directory is genuinely newly-created. + * + * @param filename directory filename + * @param error initialized error object + * @returns #TRUE on success + */ +dbus_bool_t +_dbus_create_directory (const DBusString *filename, + DBusError *error) +{ + const char *filename_c; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + filename_c = _dbus_string_get_const_data (filename); + + if (mkdir (filename_c, 0700) < 0) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to create directory %s: %s\n", + filename_c, _dbus_strerror (errno)); + return FALSE; + } + else + return TRUE; +} + /** * Appends the given filename to the given directory. * diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c index 77c5b74e..e321168b 100644 --- a/dbus/dbus-sysdeps-win.c +++ b/dbus/dbus-sysdeps-win.c @@ -2227,6 +2227,35 @@ _dbus_disable_sigpipe (void) { } +/** + * Creates a directory. Unlike _dbus_ensure_directory(), this only succeeds + * if the directory is genuinely newly-created. + * + * @param filename directory filename + * @param error initialized error object + * @returns #TRUE on success + */ +dbus_bool_t +_dbus_create_directory (const DBusString *filename, + DBusError *error) +{ + const char *filename_c; + + _DBUS_ASSERT_ERROR_IS_CLEAR (error); + + filename_c = _dbus_string_get_const_data (filename); + + if (!CreateDirectoryA (filename_c, NULL)) + { + dbus_set_error (error, DBUS_ERROR_FAILED, + "Failed to create directory %s: %s\n", + filename_c, _dbus_strerror_from_errno ()); + return FALSE; + } + else + return TRUE; +} + /** * Creates a directory; succeeds if the directory * is created or already existed. @@ -2236,7 +2265,7 @@ _dbus_disable_sigpipe (void) * @returns #TRUE on success */ dbus_bool_t -_dbus_create_directory (const DBusString *filename, +_dbus_ensure_directory (const DBusString *filename, DBusError *error) { const char *filename_c; diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h index 2ef4bf2c..543ce57f 100644 --- a/dbus/dbus-sysdeps.h +++ b/dbus/dbus-sysdeps.h @@ -412,6 +412,9 @@ DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_create_directory (const DBusString *filename, DBusError *error); DBUS_PRIVATE_EXPORT +dbus_bool_t _dbus_ensure_directory (const DBusString *filename, + DBusError *error); +DBUS_PRIVATE_EXPORT dbus_bool_t _dbus_delete_directory (const DBusString *filename, DBusError *error);