_dbus_get_tmpdir: be thread-safe
authorSimon McVittie <simon.mcvittie@collabora.co.uk>
Tue, 27 Aug 2013 13:35:47 +0000 (14:35 +0100)
committerSimon McVittie <simon.mcvittie@collabora.co.uk>
Thu, 29 Aug 2013 11:30:02 +0000 (12:30 +0100)
Sharing a static variable between threads is not safe in general,
and this function is used in the shared libdbus (for nonce files),
so it can't rely on being single-threaded.

Bug: https://bugs.freedesktop.org/show_bug.cgi?id=68610
Reviewed-by: Ralf Habacker <ralf.habacker@freenet.de>
bus/activation.c
dbus/dbus-internals.h
dbus/dbus-nonce.c
dbus/dbus-sysdeps-unix.c
dbus/dbus-sysdeps-win.c

index 4269440..e03b6fe 100644 (file)
@@ -2539,11 +2539,17 @@ dbus_bool_t
 bus_activation_service_reload_test (const DBusString *test_data_dir)
 {
   DBusString directory;
+  const char *tmp;
 
   if (!_dbus_string_init (&directory))
     return FALSE;
 
-  if (!_dbus_string_append (&directory, _dbus_get_tmpdir()))
+  tmp = _dbus_get_tmpdir ();
+
+  if (tmp == NULL)
+    return FALSE;
+
+  if (!_dbus_string_append (&directory, tmp))
     return FALSE;
 
   if (!_dbus_string_append (&directory, "/dbus-reload-test-") ||
index 0856f8f..e9ffb9e 100644 (file)
@@ -316,9 +316,10 @@ typedef enum
   _DBUS_LOCK_shutdown_funcs,
   _DBUS_LOCK_system_users,
   _DBUS_LOCK_message_cache,
-  /* index 10-11 */
+  /* index 10-12 */
   _DBUS_LOCK_shared_connections,
   _DBUS_LOCK_machine_uuid,
+  _DBUS_LOCK_sysdeps,
 
   _DBUS_N_GLOBAL_LOCKS
 } DBusGlobalLock;
index e74c2dd..ef037ef 100644 (file)
@@ -240,6 +240,7 @@ do_noncefile_create (DBusNonceFile *noncefile,
                      dbus_bool_t use_subdir)
 {
     DBusString randomStr;
+    const char *tmp;
 
     _DBUS_ASSERT_ERROR_IS_CLEAR (error);
 
@@ -257,8 +258,11 @@ do_noncefile_create (DBusNonceFile *noncefile,
         goto on_error;
       }
 
+    tmp = _dbus_get_tmpdir ();
+
     if (!_dbus_string_init (&noncefile->dir)
-        || !_dbus_string_append (&noncefile->dir, _dbus_get_tmpdir()))
+        || tmp == NULL
+        || !_dbus_string_append (&noncefile->dir, tmp))
       {
         dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL);
         goto on_error;
index 66f55d7..1dcb6f8 100644 (file)
@@ -3197,13 +3197,17 @@ _dbus_printf_string_upper_bound (const char *format,
  * Gets the temporary files directory by inspecting the environment variables
  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
  *
- * @returns location of temp directory
+ * @returns location of temp directory, or #NULL if no memory for locking
  */
 const char*
 _dbus_get_tmpdir(void)
 {
+  /* Protected by _DBUS_LOCK_sysdeps */
   static const char* tmpdir = NULL;
 
+  if (!_DBUS_LOCK (sysdeps))
+    return NULL;
+
   if (tmpdir == NULL)
     {
       /* TMPDIR is what glibc uses, then
@@ -3226,6 +3230,8 @@ _dbus_get_tmpdir(void)
         tmpdir = "/tmp";
     }
 
+  _DBUS_UNLOCK (sysdeps);
+
   _dbus_assert(tmpdir != NULL);
 
   return tmpdir;
index efeb2a6..2f5e51f 100644 (file)
@@ -2256,14 +2256,18 @@ _dbus_generate_random_bytes (DBusString *str,
  * Gets the temporary files directory by inspecting the environment variables 
  * TMPDIR, TMP, and TEMP in that order. If none of those are set "/tmp" is returned
  *
- * @returns location of temp directory
+ * @returns location of temp directory, or #NULL if no memory for locking
  */
 const char*
 _dbus_get_tmpdir(void)
 {
+  /* Protected by _DBUS_LOCK_sysdeps */
   static const char* tmpdir = NULL;
   static char buf[1000];
 
+  if (!_DBUS_LOCK (sysdeps))
+    return NULL;
+
   if (tmpdir == NULL)
     {
       char *last_slash;
@@ -2285,6 +2289,8 @@ _dbus_get_tmpdir(void)
       tmpdir = buf;
     }
 
+  _DBUS_UNLOCK (sysdeps);
+
   _dbus_assert(tmpdir != NULL);
 
   return tmpdir;