From 0b34006501e5097ca4f8877b3f60527c8f013051 Mon Sep 17 00:00:00 2001 From: Ronan Le Martret Date: Wed, 28 May 2014 15:05:20 +0200 Subject: [PATCH] Fix dbus with tizen patch Change-Id: I08e3d166b9da316e49e48c265ab2912888d0903d Signed-off-by: Ronan Le Martret --- recipes-core/dbus/dbus_1.6.18.bbappend | 16 + ...orrect-address-when-using-address-systemd.patch | 186 ++++++ ...GNUC_WARN_UNUSED_RESULT-similar-to-GLib-s.patch | 42 ++ ...on-Unix-use-pthreads-mutexes-for-fallback.patch | 147 +++++ ...s_init-call-_dbus_threads_init_platform_s.patch | 78 +++ ...s_init_default-dbus_threads_init-be-safe-.patch | 296 +++++++++ ...ed-global-mutexes-for-win_fds-sid_atom_ca.patch | 78 +++ ...ime-assertion-into-a-compile-time-asserti.patch | 30 + ...ividual-global-lock-variables-with-an-arr.patch | 734 +++++++++++++++++++++ ...-a-global-lock-automatically-initialize-l.patch | 719 ++++++++++++++++++++ ...ialize-threading-before-allocating-a-dyna.patch | 491 ++++++++++++++ ...cally-initialized-implementation-of-_dbus.patch | 122 ++++ ...king-of-smack-context-from-DBus-interface.patch | 341 ++++++++++ .../0013-Enforce-smack-policy-from-conf-file.patch | 481 ++++++++++++++ 14 files changed, 3761 insertions(+) create mode 100644 recipes-core/dbus/files/0001-Set-correct-address-when-using-address-systemd.patch create mode 100644 recipes-core/dbus/files/0002-Add-_DBUS_GNUC_WARN_UNUSED_RESULT-similar-to-GLib-s.patch create mode 100644 recipes-core/dbus/files/0003-DBusAtomic-on-Unix-use-pthreads-mutexes-for-fallback.patch create mode 100644 recipes-core/dbus/files/0004-dbus_threads_init-call-_dbus_threads_init_platform_s.patch create mode 100644 recipes-core/dbus/files/0005-dbus_threads_init_default-dbus_threads_init-be-safe-.patch create mode 100644 recipes-core/dbus/files/0006-Remove-unused-global-mutexes-for-win_fds-sid_atom_ca.patch create mode 100644 recipes-core/dbus/files/0007-Turn-a-runtime-assertion-into-a-compile-time-asserti.patch create mode 100644 recipes-core/dbus/files/0008-Replace-individual-global-lock-variables-with-an-arr.patch create mode 100644 recipes-core/dbus/files/0009-Make-taking-a-global-lock-automatically-initialize-l.patch create mode 100644 recipes-core/dbus/files/0010-Always-initialize-threading-before-allocating-a-dyna.patch create mode 100644 recipes-core/dbus/files/0011-Add-a-statically-initialized-implementation-of-_dbus.patch create mode 100644 recipes-core/dbus/files/0012-Enable-checking-of-smack-context-from-DBus-interface.patch create mode 100644 recipes-core/dbus/files/0013-Enforce-smack-policy-from-conf-file.patch diff --git a/recipes-core/dbus/dbus_1.6.18.bbappend b/recipes-core/dbus/dbus_1.6.18.bbappend index edff7f6..abc3328 100644 --- a/recipes-core/dbus/dbus_1.6.18.bbappend +++ b/recipes-core/dbus/dbus_1.6.18.bbappend @@ -4,6 +4,22 @@ SRC_URI += " file://dbus-user.service \ file://dbus-user.socket \ " +#SRC_URI += " file://0001-Set-correct-address-when-using-address-systemd.patch " + +SRC_URI += " file://0002-Add-_DBUS_GNUC_WARN_UNUSED_RESULT-similar-to-GLib-s.patch \ + file://0003-DBusAtomic-on-Unix-use-pthreads-mutexes-for-fallback.patch \ + file://0004-dbus_threads_init-call-_dbus_threads_init_platform_s.patch \ + file://0005-dbus_threads_init_default-dbus_threads_init-be-safe-.patch \ + file://0006-Remove-unused-global-mutexes-for-win_fds-sid_atom_ca.patch \ + file://0007-Turn-a-runtime-assertion-into-a-compile-time-asserti.patch \ + file://0008-Replace-individual-global-lock-variables-with-an-arr.patch \ + file://0009-Make-taking-a-global-lock-automatically-initialize-l.patch \ + file://0010-Always-initialize-threading-before-allocating-a-dyna.patch \ + file://0011-Add-a-statically-initialized-implementation-of-_dbus.patch \ + file://0012-Enable-checking-of-smack-context-from-DBus-interface.patch \ + file://0013-Enforce-smack-policy-from-conf-file.patch \ + " + do_install_append() { mkdir -p ${D}${systemd_unitdir}/user install -m 0644 ${WORKDIR}/dbus-user.service ${D}${systemd_unitdir}/user/dbus.service diff --git a/recipes-core/dbus/files/0001-Set-correct-address-when-using-address-systemd.patch b/recipes-core/dbus/files/0001-Set-correct-address-when-using-address-systemd.patch new file mode 100644 index 0000000..0f4689c --- /dev/null +++ b/recipes-core/dbus/files/0001-Set-correct-address-when-using-address-systemd.patch @@ -0,0 +1,186 @@ +From: Simon Peeters +Date: Sun, 7 Oct 2012 16:59:30 +0200 +Subject: Set correct address when using --address=systemd: + +When dbus gets launched through systemd, we need to create an address +string based on the sockets passed. + +The _dbus_append_addres_from_socket() function is responsible for +extracting the address information from the file-descriptor and +formatting it in a dbus friendly way. + +This fixes bus activation when running dbus under a systemd session. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=50962 +Signed-off-by: Simon Peeters +Applied-upstream: 1.7.0, commit:d728fdc655f17031da3bb129ab2fd17dadf0fe3a +--- + dbus/dbus-server-unix.c | 38 ++++++++++++++++++--------- + dbus/dbus-sysdeps-unix.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++++ + dbus/dbus-sysdeps-unix.h | 4 +++ + 3 files changed, 97 insertions(+), 13 deletions(-) + +diff --git a/dbus/dbus-server-unix.c b/dbus/dbus-server-unix.c +index 130f66e..d995240 100644 +--- a/dbus/dbus-server-unix.c ++++ b/dbus/dbus-server-unix.c +@@ -149,7 +149,7 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, + } + else if (strcmp (method, "systemd") == 0) + { +- int n, *fds; ++ int i, n, *fds; + DBusString address; + + n = _dbus_listen_systemd_sockets (&fds, error); +@@ -159,27 +159,39 @@ _dbus_server_listen_platform_specific (DBusAddressEntry *entry, + return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; + } + +- _dbus_string_init_const (&address, "systemd:"); ++ if (!_dbus_string_init (&address)) ++ goto systemd_oom; + +- *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL); +- if (*server_p == NULL) ++ for (i = 0; i < n; i++) + { +- int i; +- +- for (i = 0; i < n; i++) ++ if (i > 0) + { +- _dbus_close_socket (fds[i], NULL); ++ if (!_dbus_string_append (&address, ";")) ++ goto systemd_oom; + } +- dbus_free (fds); +- +- dbus_set_error (error, DBUS_ERROR_NO_MEMORY, NULL); +- return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; ++ if (!_dbus_append_address_from_socket (fds[i], &address, error)) ++ goto systemd_err; + } + ++ *server_p = _dbus_server_new_for_socket (fds, n, &address, NULL); ++ if (*server_p == NULL) ++ goto systemd_oom; ++ + dbus_free (fds); + + return DBUS_SERVER_LISTEN_OK; +- } ++ systemd_oom: ++ _DBUS_SET_OOM (error); ++ systemd_err: ++ for (i = 0; i < n; i++) ++ { ++ _dbus_close_socket (fds[i], NULL); ++ } ++ dbus_free (fds); ++ _dbus_string_free (&address); ++ ++ return DBUS_SERVER_LISTEN_DID_NOT_CONNECT; ++ } + #ifdef DBUS_ENABLE_LAUNCHD + else if (strcmp (method, "launchd") == 0) + { +diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c +index e31c735..7c9fb09 100644 +--- a/dbus/dbus-sysdeps-unix.c ++++ b/dbus/dbus-sysdeps-unix.c +@@ -55,6 +55,7 @@ + #include + #include + #include ++#include + + #ifdef HAVE_ERRNO_H + #include +@@ -4173,4 +4174,71 @@ _dbus_check_setuid (void) + #endif + } + ++/** ++ * Read the address from the socket and append it to the string ++ * ++ * @param fd the socket ++ * @param address ++ * @param error return location for error code ++ */ ++dbus_bool_t ++_dbus_append_address_from_socket (int fd, ++ DBusString *address, ++ DBusError *error) ++{ ++ union { ++ struct sockaddr sa; ++ struct sockaddr_storage storage; ++ struct sockaddr_un un; ++ struct sockaddr_in ipv4; ++ struct sockaddr_in6 ipv6; ++ } socket; ++ char hostip[INET6_ADDRSTRLEN]; ++ int size = sizeof (socket); ++ ++ if (getsockname (fd, &socket.sa, &size)) ++ goto err; ++ ++ switch (socket.sa.sa_family) ++ { ++ case AF_UNIX: ++ if (socket.un.sun_path[0]=='\0') ++ { ++ if (_dbus_string_append_printf (address, "unix:abstract=%s", &(socket.un.sun_path[1]))) ++ return TRUE; ++ } ++ else ++ { ++ if (_dbus_string_append_printf (address, "unix:path=%s", socket.un.sun_path)) ++ return TRUE; ++ } ++ break; ++ case AF_INET: ++ if (inet_ntop (AF_INET, &socket.ipv4.sin_addr, hostip, sizeof (hostip))) ++ if (_dbus_string_append_printf (address, "tcp:family=ipv4,host=%s,port=%u", ++ hostip, ntohs (socket.ipv4.sin_port))) ++ return TRUE; ++ break; ++#ifdef AF_INET6 ++ case AF_INET6: ++ if (inet_ntop (AF_INET6, &socket.ipv6.sin6_addr, hostip, sizeof (hostip))) ++ if (_dbus_string_append_printf (address, "tcp:family=ipv6,host=%s,port=%u", ++ hostip, ntohs (socket.ipv6.sin6_port))) ++ return TRUE; ++ break; ++#endif ++ default: ++ dbus_set_error (error, ++ _dbus_error_from_errno (EINVAL), ++ "Failed to read address from socket: Unknown socket type."); ++ return FALSE; ++ } ++ err: ++ dbus_set_error (error, ++ _dbus_error_from_errno (errno), ++ "Failed to open socket: %s", ++ _dbus_strerror (errno)); ++ return FALSE; ++} ++ + /* tests in dbus-sysdeps-util.c */ +diff --git a/dbus/dbus-sysdeps-unix.h b/dbus/dbus-sysdeps-unix.h +index 9b70896..a265b33 100644 +--- a/dbus/dbus-sysdeps-unix.h ++++ b/dbus/dbus-sysdeps-unix.h +@@ -138,6 +138,10 @@ dbus_bool_t _dbus_parse_uid (const DBusString *uid_str, + + void _dbus_close_all (void); + ++dbus_bool_t _dbus_append_address_from_socket (int fd, ++ DBusString *address, ++ DBusError *error); ++ + /** @} */ + + DBUS_END_DECLS diff --git a/recipes-core/dbus/files/0002-Add-_DBUS_GNUC_WARN_UNUSED_RESULT-similar-to-GLib-s.patch b/recipes-core/dbus/files/0002-Add-_DBUS_GNUC_WARN_UNUSED_RESULT-similar-to-GLib-s.patch new file mode 100644 index 0000000..62763d8 --- /dev/null +++ b/recipes-core/dbus/files/0002-Add-_DBUS_GNUC_WARN_UNUSED_RESULT-similar-to-GLib-s.patch @@ -0,0 +1,42 @@ +From: Simon McVittie +Date: Mon, 15 Apr 2013 20:40:21 +0100 +Subject: Add _DBUS_GNUC_WARN_UNUSED_RESULT, similar to GLib's + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Ralf Habacker +Reviewed-by: Alban Crequy +Applied-upstream: 1.7.4, commit:7ac9b68220a2f48bc2942aaa909d6ba1f4605f73 +Bug-Tizen: TZPC-1971 +Change-Id: I9944ae3a1e9901728bbc3bedbcc6474022db586f +--- + dbus/dbus-macros.h | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/dbus/dbus-macros.h b/dbus/dbus-macros.h +index dcd3eeb..cae4100 100644 +--- a/dbus/dbus-macros.h ++++ b/dbus/dbus-macros.h +@@ -88,13 +88,21 @@ + #define DBUS_ALLOC_SIZE2(x,y) + #endif + ++#if (__GNUC__ > 3) || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4) ++#define _DBUS_GNUC_WARN_UNUSED_RESULT __attribute__((warn_unused_result)) ++#else ++#define _DBUS_GNUC_WARN_UNUSED_RESULT ++#endif ++ + /** @def _DBUS_GNUC_PRINTF + * used to tell gcc about printf format strings + */ + /** @def _DBUS_GNUC_NORETURN + * used to tell gcc about functions that never return, such as _dbus_abort() + */ +- ++/** @def _DBUS_GNUC_WARN_UNUSED_RESULT ++ * used to tell gcc about functions whose result must be used ++ */ + + /* Normally docs are in .c files, but there isn't a .c file for this. */ + /** diff --git a/recipes-core/dbus/files/0003-DBusAtomic-on-Unix-use-pthreads-mutexes-for-fallback.patch b/recipes-core/dbus/files/0003-DBusAtomic-on-Unix-use-pthreads-mutexes-for-fallback.patch new file mode 100644 index 0000000..bf7ffff --- /dev/null +++ b/recipes-core/dbus/files/0003-DBusAtomic-on-Unix-use-pthreads-mutexes-for-fallback.patch @@ -0,0 +1,147 @@ +From: Simon McVittie +Date: Mon, 15 Apr 2013 13:51:19 +0100 +Subject: DBusAtomic: on Unix, use pthreads mutexes for fallback + +On pthreads platforms, POSIX guarantees that we can "allocate" mutexes +as library-global variables, without involving malloc. This means we +don't need to error-check their allocation - if the dynamic linker +succeeds, then we have enough memory for all our globals - which is an +important step towards being thread-safe by default. In particular, +making atomic operations never rely on DBusMutex means that we are free +to implement parts of DBusMutex in terms of DBusAtomic, if it would help. + +We do not currently support any non-Windows platform that does not have +pthreads. This is unlikely to change. + +On Windows, we already used real atomic operations; we can just +delete the unused global variable. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Ralf Habacker +Applied-upstream: 1.7.4, commit:c36f21a2e91730e9ae52e8945305aa3072f0e508 +Bug-Tizen: TZPC-1971 +Change-Id: I91d99a86f25d49d63d79eebfe85767bb8cc66170 +--- + dbus/dbus-internals.h | 5 ----- + dbus/dbus-sysdeps-unix.c | 27 ++++++++++++++++++++------- + dbus/dbus-sysdeps-win.c | 2 -- + dbus/dbus-threads.c | 3 --- + 4 files changed, 20 insertions(+), 17 deletions(-) + +diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h +index 8036a2b..eaf9603 100644 +--- a/dbus/dbus-internals.h ++++ b/dbus/dbus-internals.h +@@ -327,12 +327,7 @@ _DBUS_DECLARE_GLOBAL_LOCK (win_fds); + _DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache); + _DBUS_DECLARE_GLOBAL_LOCK (machine_uuid); + +-#if !DBUS_USE_SYNC +-_DBUS_DECLARE_GLOBAL_LOCK (atomic); +-#define _DBUS_N_GLOBAL_LOCKS (15) +-#else + #define _DBUS_N_GLOBAL_LOCKS (14) +-#endif + + dbus_bool_t _dbus_threads_init_debug (void); + +diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c +index 7c9fb09..a67f5d3 100644 +--- a/dbus/dbus-sysdeps-unix.c ++++ b/dbus/dbus-sysdeps-unix.c +@@ -82,6 +82,10 @@ + + #include "sd-daemon.h" + ++#if !DBUS_USE_SYNC ++#include ++#endif ++ + #ifndef O_BINARY + #define O_BINARY 0 + #endif +@@ -2428,7 +2432,12 @@ _dbus_parse_uid (const DBusString *uid_str, + } + + #if !DBUS_USE_SYNC +-_DBUS_DEFINE_GLOBAL_LOCK (atomic); ++/* To be thread-safe by default on platforms that don't necessarily have ++ * atomic operations (notably Debian armel, which is armv4t), we must ++ * use a mutex that can be initialized statically, like this. ++ * GLib >= 2.32 uses a similar system. ++ */ ++static pthread_mutex_t atomic_mutex = PTHREAD_MUTEX_INITIALIZER; + #endif + + /** +@@ -2444,10 +2453,12 @@ _dbus_atomic_inc (DBusAtomic *atomic) + return __sync_add_and_fetch(&atomic->value, 1)-1; + #else + dbus_int32_t res; +- _DBUS_LOCK (atomic); ++ ++ pthread_mutex_lock (&atomic_mutex); + res = atomic->value; + atomic->value += 1; +- _DBUS_UNLOCK (atomic); ++ pthread_mutex_unlock (&atomic_mutex); ++ + return res; + #endif + } +@@ -2466,10 +2477,11 @@ _dbus_atomic_dec (DBusAtomic *atomic) + #else + dbus_int32_t res; + +- _DBUS_LOCK (atomic); ++ pthread_mutex_lock (&atomic_mutex); + res = atomic->value; + atomic->value -= 1; +- _DBUS_UNLOCK (atomic); ++ pthread_mutex_unlock (&atomic_mutex); ++ + return res; + #endif + } +@@ -2490,9 +2502,10 @@ _dbus_atomic_get (DBusAtomic *atomic) + #else + dbus_int32_t res; + +- _DBUS_LOCK (atomic); ++ pthread_mutex_lock (&atomic_mutex); + res = atomic->value; +- _DBUS_UNLOCK (atomic); ++ pthread_mutex_unlock (&atomic_mutex); ++ + return res; + #endif + } +diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c +index c42316f..a17b210 100644 +--- a/dbus/dbus-sysdeps-win.c ++++ b/dbus/dbus-sysdeps-win.c +@@ -3084,8 +3084,6 @@ _dbus_get_standard_system_servicedirs (DBusList **dirs) + return TRUE; + } + +-_DBUS_DEFINE_GLOBAL_LOCK (atomic); +- + /** + * Atomically increments an integer + * +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index bb1169d..b464629 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -496,9 +496,6 @@ init_locks (void) + LOCK_ADDR (pending_call_slots), + LOCK_ADDR (server_slots), + LOCK_ADDR (message_slots), +-#if !DBUS_USE_SYNC +- LOCK_ADDR (atomic), +-#endif + LOCK_ADDR (bus), + LOCK_ADDR (bus_datas), + LOCK_ADDR (shutdown_funcs), diff --git a/recipes-core/dbus/files/0004-dbus_threads_init-call-_dbus_threads_init_platform_s.patch b/recipes-core/dbus/files/0004-dbus_threads_init-call-_dbus_threads_init_platform_s.patch new file mode 100644 index 0000000..faf6f57 --- /dev/null +++ b/recipes-core/dbus/files/0004-dbus_threads_init-call-_dbus_threads_init_platform_s.patch @@ -0,0 +1,78 @@ +From: Simon McVittie +Date: Mon, 15 Apr 2013 13:54:39 +0100 +Subject: dbus_threads_init: call _dbus_threads_init_platform_specific() + +This reverses the relationship between these two functions. +Previously, dbus_threads_init() wouldn't allocate dbus_cond_event_tls +on Windows, call check_monotonic_clock on Unix, or call +_dbus_check_setuid on Unix. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Ralf Habacker +Applied-upstream: 1.7.4, commit:eabf6c42a1b779f57f2c08d35772035788657579 +Bug-Tizen: TZPC-1971 +Change-Id: Ice70cf1f3e2202b72016daf619c89206b96aac47 +--- + dbus/dbus-sysdeps-pthread.c | 3 ++- + dbus/dbus-sysdeps-thread-win.c | 2 +- + dbus/dbus-threads.c | 7 ++++--- + 3 files changed, 7 insertions(+), 5 deletions(-) + +diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c +index c60457b..36a1e4b 100644 +--- a/dbus/dbus-sysdeps-pthread.c ++++ b/dbus/dbus-sysdeps-pthread.c +@@ -281,5 +281,6 @@ _dbus_threads_init_platform_specific (void) + */ + check_monotonic_clock (); + (void) _dbus_check_setuid (); +- return dbus_threads_init (NULL); ++ ++ return TRUE; + } +diff --git a/dbus/dbus-sysdeps-thread-win.c b/dbus/dbus-sysdeps-thread-win.c +index e30e7b8..4c4442a 100644 +--- a/dbus/dbus-sysdeps-thread-win.c ++++ b/dbus/dbus-sysdeps-thread-win.c +@@ -269,6 +269,6 @@ _dbus_threads_init_platform_specific (void) + return FALSE; + } + +- return dbus_threads_init (NULL); ++ return TRUE; + } + +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index b464629..e7f2eb7 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -584,7 +584,8 @@ dbus_threads_init (const DBusThreadFunctions *functions) + if (thread_init_generation == _dbus_current_generation) + return TRUE; + +- if (!init_locks ()) ++ if (!_dbus_threads_init_platform_specific() || ++ !init_locks ()) + return FALSE; + + thread_init_generation = _dbus_current_generation; +@@ -613,7 +614,7 @@ dbus_threads_init (const DBusThreadFunctions *functions) + dbus_bool_t + dbus_threads_init_default (void) + { +- return _dbus_threads_init_platform_specific (); ++ return dbus_threads_init (NULL); + } + + +@@ -624,7 +625,7 @@ dbus_threads_init_default (void) + dbus_bool_t + _dbus_threads_init_debug (void) + { +- return _dbus_threads_init_platform_specific(); ++ return dbus_threads_init (NULL); + } + + #endif /* DBUS_BUILD_TESTS */ diff --git a/recipes-core/dbus/files/0005-dbus_threads_init_default-dbus_threads_init-be-safe-.patch b/recipes-core/dbus/files/0005-dbus_threads_init_default-dbus_threads_init-be-safe-.patch new file mode 100644 index 0000000..41519a4 --- /dev/null +++ b/recipes-core/dbus/files/0005-dbus_threads_init_default-dbus_threads_init-be-safe-.patch @@ -0,0 +1,296 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 12:07:23 +0100 +Subject: dbus_threads_init_default, + dbus_threads_init: be safe to call at any time + +On Unix, we use a pthreads mutex, which can be allocated and +initialized in global memory. + +On Windows, we use a CRITICAL_SECTION, together with a call to +InitializeCriticalSection() from the constructor of a global static +C++ object (thanks to Ralf Habacker for suggesting this approach). + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Ralf Habacker +Applied-upstream: 1.7.4, commit:17a23d08b51cf21a2110047649a86445e99e2b3f +Bug-Tizen: TZPC-1971 +Reviewed-by: Anas Nashif +Change-Id: Id6aa81b7d553965c4c6f511e2410673c2f222a66 +--- + cmake/dbus/CMakeLists.txt | 1 + + dbus/Makefile.am | 1 + + dbus/dbus-init-win.cpp | 52 ++++++++++++++++++++++++++++++++++++++++++ + dbus/dbus-memory.c | 7 ++++++ + dbus/dbus-sysdeps-pthread.c | 14 ++++++++++++ + dbus/dbus-sysdeps-thread-win.c | 28 +++++++++++++++++++++++ + dbus/dbus-sysdeps-win.h | 3 +++ + dbus/dbus-sysdeps.h | 12 ++++++++++ + dbus/dbus-threads.c | 28 +++++++++++++++++------ + 9 files changed, 139 insertions(+), 7 deletions(-) + create mode 100644 dbus/dbus-init-win.cpp + +diff --git a/cmake/dbus/CMakeLists.txt b/cmake/dbus/CMakeLists.txt +index d09e63d..9fcbb80 100644 +--- a/cmake/dbus/CMakeLists.txt ++++ b/cmake/dbus/CMakeLists.txt +@@ -186,6 +186,7 @@ set (DBUS_UTIL_HEADERS + if (WIN32) + set (DBUS_SHARED_SOURCES ${DBUS_SHARED_SOURCES} + ${DBUS_DIR}/dbus-file-win.c ++ ${DBUS_DIR}/dbus-init-win.cpp + ${DBUS_DIR}/dbus-sysdeps-win.c + ${DBUS_DIR}/dbus-pipe-win.c + ${DBUS_DIR}/dbus-sysdeps-thread-win.c +diff --git a/dbus/Makefile.am b/dbus/Makefile.am +index bb5ccca..0e54c9f 100644 +--- a/dbus/Makefile.am ++++ b/dbus/Makefile.am +@@ -68,6 +68,7 @@ endif + DBUS_SHARED_arch_sources = \ + $(wince_source) \ + dbus-file-win.c \ ++ dbus-init-win.cpp \ + dbus-pipe-win.c \ + dbus-sockets-win.h \ + dbus-sysdeps-win.c \ +diff --git a/dbus/dbus-init-win.cpp b/dbus/dbus-init-win.cpp +new file mode 100644 +index 0000000..687f248 +--- /dev/null ++++ b/dbus/dbus-init-win.cpp +@@ -0,0 +1,52 @@ ++/* ++ * dbus-init-win.cpp - once-per-process initialization ++ * ++ * Copyright © 2013 Intel Corporation ++ * ++ * Licensed under the Academic Free License version 2.1 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA ++ * ++ */ ++ ++#include ++ ++extern "C" ++{ ++#include "dbus-sysdeps-win.h" ++} ++ ++class DBusInternalInit ++ { ++ public: ++ DBusInternalInit () ++ { ++ _dbus_threads_windows_init_global (); ++ } ++ ++ void must_not_be_omitted () ++ { ++ } ++ }; ++ ++static DBusInternalInit init; ++ ++extern "C" void ++_dbus_threads_windows_ensure_ctor_linked () ++{ ++ /* Do nothing significant, just ensure that the global initializer gets ++ * linked in. */ ++ init.must_not_be_omitted (); ++} +diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c +index a033b54..317e37e 100644 +--- a/dbus/dbus-memory.c ++++ b/dbus/dbus-memory.c +@@ -26,6 +26,7 @@ + #include "dbus-internals.h" + #include "dbus-sysdeps.h" + #include "dbus-list.h" ++#include "dbus-threads.h" + #include + + /** +@@ -890,7 +891,13 @@ dbus_shutdown (void) + dbus_free (c); + } + ++ /* We wrap this in the thread-initialization lock because ++ * dbus_threads_init() uses the current generation to tell whether ++ * we're initialized, so we need to make sure that un-initializing ++ * propagates into all threads. */ ++ _dbus_threads_lock_platform_specific (); + _dbus_current_generation += 1; ++ _dbus_threads_unlock_platform_specific (); + } + + /** @} */ /** End of public API docs block */ +diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c +index 36a1e4b..1b5d0ba 100644 +--- a/dbus/dbus-sysdeps-pthread.c ++++ b/dbus/dbus-sysdeps-pthread.c +@@ -284,3 +284,17 @@ _dbus_threads_init_platform_specific (void) + + return TRUE; + } ++ ++static pthread_mutex_t init_mutex = PTHREAD_MUTEX_INITIALIZER; ++ ++void ++_dbus_threads_lock_platform_specific (void) ++{ ++ pthread_mutex_lock (&init_mutex); ++} ++ ++void ++_dbus_threads_unlock_platform_specific (void) ++{ ++ pthread_mutex_unlock (&init_mutex); ++} +diff --git a/dbus/dbus-sysdeps-thread-win.c b/dbus/dbus-sysdeps-thread-win.c +index 4c4442a..0887a54 100644 +--- a/dbus/dbus-sysdeps-thread-win.c ++++ b/dbus/dbus-sysdeps-thread-win.c +@@ -30,6 +30,21 @@ + + #include + ++static dbus_bool_t global_init_done = FALSE; ++static CRITICAL_SECTION init_lock; ++ ++/* Called from C++ code in dbus-init-win.cpp. */ ++void ++_dbus_threads_windows_init_global (void) ++{ ++ /* this ensures that the object that acts as our global constructor ++ * actually gets linked in when we're linked statically */ ++ _dbus_threads_windows_ensure_ctor_linked (); ++ ++ InitializeCriticalSection (&init_lock); ++ global_init_done = TRUE; ++} ++ + struct DBusCondVar { + DBusList *list; /**< list thread-local-stored events waiting on the cond variable */ + CRITICAL_SECTION lock; /**< lock protecting the list */ +@@ -272,3 +287,16 @@ _dbus_threads_init_platform_specific (void) + return TRUE; + } + ++void ++_dbus_threads_lock_platform_specific (void) ++{ ++ _dbus_assert (global_init_done); ++ EnterCriticalSection (&init_lock); ++} ++ ++void ++_dbus_threads_unlock_platform_specific (void) ++{ ++ _dbus_assert (global_init_done); ++ LeaveCriticalSection (&init_lock); ++} +diff --git a/dbus/dbus-sysdeps-win.h b/dbus/dbus-sysdeps-win.h +index 74624b7..5e7f1e4 100644 +--- a/dbus/dbus-sysdeps-win.h ++++ b/dbus/dbus-sysdeps-win.h +@@ -85,6 +85,9 @@ dbus_bool_t _dbus_get_config_file_name(DBusString *config_file, + + dbus_bool_t _dbus_get_install_root(char *prefix, int len); + ++void _dbus_threads_windows_init_global (void); ++void _dbus_threads_windows_ensure_ctor_linked (void); ++ + #endif + + /** @} end of sysdeps-win.h */ +diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h +index eee9160..c48d50f 100644 +--- a/dbus/dbus-sysdeps.h ++++ b/dbus/dbus-sysdeps.h +@@ -507,6 +507,18 @@ dbus_bool_t _dbus_read_local_machine_uuid (DBusGUID *machine_id, + */ + dbus_bool_t _dbus_threads_init_platform_specific (void); + ++/** ++ * Lock a static mutex used to protect _dbus_threads_init_platform_specific(). ++ * ++ * On Windows, this is currently unimplemented and does nothing. ++ */ ++void _dbus_threads_lock_platform_specific (void); ++ ++/** ++ * Undo _dbus_threads_lock_platform_specific(). ++ */ ++void _dbus_threads_unlock_platform_specific (void); ++ + dbus_bool_t _dbus_split_paths_and_append (DBusString *dirs, + const char *suffix, + DBusList **dir_list); +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index e7f2eb7..9a505de 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -581,15 +581,24 @@ init_locks (void) + dbus_bool_t + dbus_threads_init (const DBusThreadFunctions *functions) + { ++ _dbus_threads_lock_platform_specific (); ++ + if (thread_init_generation == _dbus_current_generation) +- return TRUE; ++ { ++ _dbus_threads_unlock_platform_specific (); ++ return TRUE; ++ } + + if (!_dbus_threads_init_platform_specific() || + !init_locks ()) +- return FALSE; ++ { ++ _dbus_threads_unlock_platform_specific (); ++ return FALSE; ++ } + + thread_init_generation = _dbus_current_generation; +- ++ ++ _dbus_threads_unlock_platform_specific (); + return TRUE; + } + +@@ -600,11 +609,16 @@ dbus_threads_init (const DBusThreadFunctions *functions) + /** + * Initializes threads. If this function is not called, the D-Bus + * library will not lock any data structures. If it is called, D-Bus +- * will do locking, at some cost in efficiency. Note that this +- * function must be called BEFORE the second thread is started. ++ * will do locking, at some cost in efficiency. ++ * ++ * Since D-Bus 1.7 it is safe to call this function from any thread, ++ * any number of times (but it must be called before any other ++ * libdbus API is used). + * +- * It's safe to call dbus_threads_init_default() as many times as you +- * want, but only the first time will have an effect. ++ * In D-Bus 1.6 or older, this function must be called in the main thread ++ * before any other thread starts. As a result, it is not sufficient to ++ * call this function in a library or plugin, unless the library or plugin ++ * imposes a similar requirement on its callers. + * + * dbus_shutdown() reverses the effects of this function when it + * resets all global state in libdbus. diff --git a/recipes-core/dbus/files/0006-Remove-unused-global-mutexes-for-win_fds-sid_atom_ca.patch b/recipes-core/dbus/files/0006-Remove-unused-global-mutexes-for-win_fds-sid_atom_ca.patch new file mode 100644 index 0000000..6901fd5 --- /dev/null +++ b/recipes-core/dbus/files/0006-Remove-unused-global-mutexes-for-win_fds-sid_atom_ca.patch @@ -0,0 +1,78 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 12:14:02 +0100 +Subject: Remove unused global mutexes for win_fds, sid_atom_cache + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Ralf Habacker +Applied-upstream: 1.7.4, commit:d35f64339e401a7a47c1b088ef26e3dcb202cb9d +Bug-Tizen: TZPC-1971 +Reviewed-by: Anas Nashif +Change-Id: I9619eaf477eaf1763133772b95e3845dd7c2b62e +--- + dbus/dbus-internals.h | 10 ++++------ + dbus/dbus-sysdeps.c | 2 -- + dbus/dbus-threads.c | 2 -- + 3 files changed, 4 insertions(+), 10 deletions(-) + +diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h +index eaf9603..336d22e 100644 +--- a/dbus/dbus-internals.h ++++ b/dbus/dbus-internals.h +@@ -309,25 +309,23 @@ extern int _dbus_current_generation; + #define _DBUS_LOCK(name) _dbus_rmutex_lock (_dbus_lock_##name) + #define _DBUS_UNLOCK(name) _dbus_rmutex_unlock (_dbus_lock_##name) + +-/* 1-5 */ ++/* index 0-4 */ + _DBUS_DECLARE_GLOBAL_LOCK (list); + _DBUS_DECLARE_GLOBAL_LOCK (connection_slots); + _DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots); + _DBUS_DECLARE_GLOBAL_LOCK (server_slots); + _DBUS_DECLARE_GLOBAL_LOCK (message_slots); +-/* 5-10 */ ++/* index 5-9 */ + _DBUS_DECLARE_GLOBAL_LOCK (bus); + _DBUS_DECLARE_GLOBAL_LOCK (bus_datas); + _DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs); + _DBUS_DECLARE_GLOBAL_LOCK (system_users); + _DBUS_DECLARE_GLOBAL_LOCK (message_cache); +-/* 10-14 */ ++/* index 10-11 */ + _DBUS_DECLARE_GLOBAL_LOCK (shared_connections); +-_DBUS_DECLARE_GLOBAL_LOCK (win_fds); +-_DBUS_DECLARE_GLOBAL_LOCK (sid_atom_cache); + _DBUS_DECLARE_GLOBAL_LOCK (machine_uuid); + +-#define _DBUS_N_GLOBAL_LOCKS (14) ++#define _DBUS_N_GLOBAL_LOCKS (12) + + dbus_bool_t _dbus_threads_init_debug (void); + +diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c +index 04fb8d7..4e14ac3 100644 +--- a/dbus/dbus-sysdeps.c ++++ b/dbus/dbus-sysdeps.c +@@ -46,8 +46,6 @@ + #include + #endif + +-_DBUS_DEFINE_GLOBAL_LOCK (win_fds); +-_DBUS_DEFINE_GLOBAL_LOCK (sid_atom_cache); + _DBUS_DEFINE_GLOBAL_LOCK (system_users); + + #ifdef DBUS_WIN +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index 9a505de..9fbbae5 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -489,8 +489,6 @@ init_locks (void) + DBusRMutex ***dynamic_global_locks; + DBusRMutex **global_locks[] = { + #define LOCK_ADDR(name) (& _dbus_lock_##name) +- LOCK_ADDR (win_fds), +- LOCK_ADDR (sid_atom_cache), + LOCK_ADDR (list), + LOCK_ADDR (connection_slots), + LOCK_ADDR (pending_call_slots), diff --git a/recipes-core/dbus/files/0007-Turn-a-runtime-assertion-into-a-compile-time-asserti.patch b/recipes-core/dbus/files/0007-Turn-a-runtime-assertion-into-a-compile-time-asserti.patch new file mode 100644 index 0000000..396ca3f --- /dev/null +++ b/recipes-core/dbus/files/0007-Turn-a-runtime-assertion-into-a-compile-time-asserti.patch @@ -0,0 +1,30 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 12:14:14 +0100 +Subject: Turn a runtime assertion into a compile-time assertion + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Ralf Habacker +Applied-upstream: 1.7.4, commit:24a9b93021908b6f2b20eaacc1b36fa8fb24edb4 +Bug-Tizen: TZPC-1971 +Reviewed-by: Anas Nashif +Change-Id: I2784b0aa9046fba5a83065d32305c127a2a2dc78 +--- + dbus/dbus-threads.c | 3 +-- + 1 file changed, 1 insertion(+), 2 deletions(-) + +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index 9fbbae5..43676bc 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -504,8 +504,7 @@ init_locks (void) + #undef LOCK_ADDR + }; + +- _dbus_assert (_DBUS_N_ELEMENTS (global_locks) == +- _DBUS_N_GLOBAL_LOCKS); ++ _DBUS_STATIC_ASSERT (_DBUS_N_ELEMENTS (global_locks) == _DBUS_N_GLOBAL_LOCKS); + + i = 0; + diff --git a/recipes-core/dbus/files/0008-Replace-individual-global-lock-variables-with-an-arr.patch b/recipes-core/dbus/files/0008-Replace-individual-global-lock-variables-with-an-arr.patch new file mode 100644 index 0000000..e87c4f3 --- /dev/null +++ b/recipes-core/dbus/files/0008-Replace-individual-global-lock-variables-with-an-arr.patch @@ -0,0 +1,734 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 15:39:54 +0100 +Subject: Replace individual global-lock variables with an array of DBusRMutex + * + +This means we can use a much simpler code structure in data-slot +allocators: instead of giving them a DBusRMutex ** at first-allocation, +we can just give them an index into the array, which can be done +statically. + +It doesn't make us any more thread-safe-by-default - the mutexes will +only actually be used if threads were already initialized - but it's +substantially better than nothing. + +These locks really do have to be recursive: for instance, +internal_bus_get() calls dbus_bus_register() under the bus lock, +and dbus_bus_register() can call _dbus_connection_close_possibly_shared(), +which takes the bus lock. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Ralf Habacker +Reviewed-by: Anas Nashif +Applied-upstream: 1.7.6, commit:c80c20af46c5f43dcbe672f2c6d8aec0e7f2bbd6 +Bug-Tizen: TZPC-1971 +Change-Id: I22a31a9278b5f9c88557c54723f86827a91de818 +--- + Doxyfile.in | 1 - + cmake/Doxyfile.cmake | 1 - + dbus/dbus-bus.c | 13 ------ + dbus/dbus-connection.c | 7 ++-- + dbus/dbus-dataslot.c | 62 +++++++++-------------------- + dbus/dbus-dataslot.h | 8 ++-- + dbus/dbus-internals.c | 19 +-------- + dbus/dbus-internals.h | 59 ++++++++++++++++------------ + dbus/dbus-list.c | 2 +- + dbus/dbus-memory.c | 18 ++++++--- + dbus/dbus-message.c | 7 ++-- + dbus/dbus-pending-call.c | 5 +-- + dbus/dbus-server.c | 6 +-- + dbus/dbus-sysdeps.c | 2 - + dbus/dbus-threads.c | 100 +++++++++++++++++++++-------------------------- + 15 files changed, 126 insertions(+), 184 deletions(-) + +diff --git a/Doxyfile.in b/Doxyfile.in +index afac639..f0a37ed 100644 +--- a/Doxyfile.in ++++ b/Doxyfile.in +@@ -147,7 +147,6 @@ PREDEFINED = "DBUS_BEGIN_DECLS=" \ + "DBUS_END_DECLS=" \ + "DOXYGEN_SHOULD_SKIP_THIS" \ + "DBUS_GNUC_DEPRECATED=" \ +- "_DBUS_DEFINE_GLOBAL_LOCK(name)=" \ + "_DBUS_GNUC_PRINTF(from,to)=" + SKIP_FUNCTION_MACROS = YES + #--------------------------------------------------------------------------- +diff --git a/cmake/Doxyfile.cmake b/cmake/Doxyfile.cmake +index e00984e..3c63d95 100644 +--- a/cmake/Doxyfile.cmake ++++ b/cmake/Doxyfile.cmake +@@ -147,7 +147,6 @@ PREDEFINED = "DBUS_BEGIN_DECLS=" \ + "DBUS_END_DECLS=" \ + "DOXYGEN_SHOULD_SKIP_THIS" \ + "DBUS_GNUC_DEPRECATED=" \ +- "_DBUS_DEFINE_GLOBAL_LOCK(name)=" \ + "_DBUS_GNUC_PRINTF(from,to)=" \ + "DBUS_EXPORT=" + SKIP_FUNCTION_MACROS = YES +diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c +index fadc3a8..7a31cbd 100644 +--- a/dbus/dbus-bus.c ++++ b/dbus/dbus-bus.c +@@ -95,19 +95,6 @@ static DBusBusType activation_bus_type = DBUS_BUS_STARTER; + + static dbus_bool_t initialized = FALSE; + +-/** +- * Lock for globals in this file +- */ +-_DBUS_DEFINE_GLOBAL_LOCK (bus); +- +-/** +- * Global lock covering all BusData on any connection. The bet is +- * that some lock contention is better than more memory +- * for a per-connection lock, but it's tough to imagine it mattering +- * either way. +- */ +-_DBUS_DEFINE_GLOBAL_LOCK (bus_datas); +- + static void + addresses_shutdown_func (void *data) + { +diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c +index 66315b3..03ee066 100644 +--- a/dbus/dbus-connection.c ++++ b/dbus/dbus-connection.c +@@ -1531,7 +1531,7 @@ _dbus_connection_handle_watch (DBusWatch *watch, + return retval; + } + +-_DBUS_DEFINE_GLOBAL_LOCK (shared_connections); ++/* Protected by _DBUS_LOCK (shared_connections) */ + static DBusHashTable *shared_connections = NULL; + static DBusList *shared_connections_no_guid = NULL; + +@@ -5852,8 +5852,8 @@ dbus_connection_list_registered (DBusConnection *connection, + return retval; + } + +-static DBusDataSlotAllocator slot_allocator; +-_DBUS_DEFINE_GLOBAL_LOCK (connection_slots); ++static DBusDataSlotAllocator slot_allocator = ++ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (connection_slots)); + + /** + * Allocates an integer ID to be used for storing application-specific +@@ -5873,7 +5873,6 @@ dbus_bool_t + dbus_connection_allocate_data_slot (dbus_int32_t *slot_p) + { + return _dbus_data_slot_allocator_alloc (&slot_allocator, +- &_DBUS_LOCK_NAME (connection_slots), + slot_p); + } + +diff --git a/dbus/dbus-dataslot.c b/dbus/dbus-dataslot.c +index 0369612..b3c8090 100644 +--- a/dbus/dbus-dataslot.c ++++ b/dbus/dbus-dataslot.c +@@ -43,13 +43,14 @@ + * @param allocator the allocator to initialize + */ + dbus_bool_t +-_dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator) ++_dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator, ++ DBusGlobalLock lock) + { + allocator->allocated_slots = NULL; + allocator->n_allocated_slots = 0; + allocator->n_used_slots = 0; +- allocator->lock_loc = NULL; +- ++ allocator->lock = lock; ++ + return TRUE; + } + +@@ -61,29 +62,16 @@ _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator) + * is allocated and stored at *slot_id_p. + * + * @param allocator the allocator +- * @param mutex_loc the location lock for this allocator + * @param slot_id_p address to fill with the slot ID + * @returns #TRUE on success + */ + dbus_bool_t + _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, +- DBusRMutex **mutex_loc, + dbus_int32_t *slot_id_p) + { + dbus_int32_t slot; + +- _dbus_rmutex_lock (*mutex_loc); +- +- if (allocator->n_allocated_slots == 0) +- { +- _dbus_assert (allocator->lock_loc == NULL); +- allocator->lock_loc = mutex_loc; +- } +- else if (allocator->lock_loc != mutex_loc) +- { +- _dbus_warn_check_failed ("D-Bus threads were initialized after first using the D-Bus library. If your application does not directly initialize threads or use D-Bus, keep in mind that some library or plugin may have used D-Bus or initialized threads behind your back. You can often fix this problem by calling dbus_init_threads() or dbus_g_threads_init() early in your main() method, before D-Bus is used.\n"); +- _dbus_assert_not_reached ("exiting"); +- } ++ _dbus_lock (allocator->lock); + + if (*slot_id_p >= 0) + { +@@ -146,7 +134,7 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, + slot, allocator, allocator->n_allocated_slots, allocator->n_used_slots); + + out: +- _dbus_rmutex_unlock (*(allocator->lock_loc)); ++ _dbus_unlock (allocator->lock); + return slot >= 0; + } + +@@ -165,7 +153,7 @@ void + _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, + dbus_int32_t *slot_id_p) + { +- _dbus_rmutex_lock (*(allocator->lock_loc)); ++ _dbus_lock (allocator->lock); + + _dbus_assert (*slot_id_p < allocator->n_allocated_slots); + _dbus_assert (allocator->allocated_slots[*slot_id_p].slot_id == *slot_id_p); +@@ -175,7 +163,7 @@ _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, + + if (allocator->allocated_slots[*slot_id_p].refcount > 0) + { +- _dbus_rmutex_unlock (*(allocator->lock_loc)); ++ _dbus_unlock (allocator->lock); + return; + } + +@@ -190,19 +178,12 @@ _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, + + if (allocator->n_used_slots == 0) + { +- DBusRMutex **mutex_loc = allocator->lock_loc; +- + dbus_free (allocator->allocated_slots); + allocator->allocated_slots = NULL; + allocator->n_allocated_slots = 0; +- allocator->lock_loc = NULL; +- +- _dbus_rmutex_unlock (*mutex_loc); +- } +- else +- { +- _dbus_rmutex_unlock (*(allocator->lock_loc)); + } ++ ++ _dbus_unlock (allocator->lock); + } + + /** +@@ -247,10 +228,10 @@ _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator, + * be e.g. realloc()ing allocated_slots. We avoid doing this if asserts + * are disabled, since then the asserts are empty. + */ +- _dbus_rmutex_lock (*(allocator->lock_loc)); ++ _dbus_lock (allocator->lock); + _dbus_assert (slot < allocator->n_allocated_slots); + _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); +- _dbus_rmutex_unlock (*(allocator->lock_loc)); ++ _dbus_unlock (allocator->lock); + #endif + + if (slot >= list->n_slots) +@@ -304,11 +285,11 @@ _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator, + * be e.g. realloc()ing allocated_slots. We avoid doing this if asserts + * are disabled, since then the asserts are empty. + */ +- _dbus_rmutex_lock (*(allocator->lock_loc)); ++ _dbus_lock (allocator->lock); + _dbus_assert (slot >= 0); + _dbus_assert (slot < allocator->n_allocated_slots); + _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); +- _dbus_rmutex_unlock (*(allocator->lock_loc)); ++ _dbus_unlock (allocator->lock); + #endif + + if (slot >= list->n_slots) +@@ -384,17 +365,12 @@ _dbus_data_slot_test (void) + int i; + DBusFreeFunction old_free_func; + void *old_data; +- DBusRMutex *mutex; +- +- if (!_dbus_data_slot_allocator_init (&allocator)) ++ ++ if (!_dbus_data_slot_allocator_init (&allocator, _DBUS_LOCK_server_slots)) + _dbus_assert_not_reached ("no memory for allocator"); + + _dbus_data_slot_list_init (&list); + +- _dbus_rmutex_new_at_location (&mutex); +- if (mutex == NULL) +- _dbus_assert_not_reached ("failed to alloc mutex"); +- + #define N_SLOTS 100 + + i = 0; +@@ -405,8 +381,8 @@ _dbus_data_slot_test (void) + * here. + */ + dbus_int32_t tmp = -1; +- +- _dbus_data_slot_allocator_alloc (&allocator, &mutex, &tmp); ++ ++ _dbus_data_slot_allocator_alloc (&allocator, &tmp); + + if (tmp != i) + _dbus_assert_not_reached ("did not allocate slots in numeric order\n"); +@@ -471,8 +447,6 @@ _dbus_data_slot_test (void) + ++i; + } + +- _dbus_rmutex_free_at_location (&mutex); +- + return TRUE; + } + +diff --git a/dbus/dbus-dataslot.h b/dbus/dbus-dataslot.h +index 3d9d5ed..1e04fcb 100644 +--- a/dbus/dbus-dataslot.h ++++ b/dbus/dbus-dataslot.h +@@ -57,9 +57,11 @@ struct DBusDataSlotAllocator + DBusAllocatedSlot *allocated_slots; /**< Allocated slots */ + int n_allocated_slots; /**< number of slots malloc'd */ + int n_used_slots; /**< number of slots used */ +- DBusRMutex **lock_loc; /**< location of thread lock */ ++ DBusGlobalLock lock; /**< index of thread lock */ + }; + ++#define _DBUS_DATA_SLOT_ALLOCATOR_INIT(x) { NULL, 0, 0, x } ++ + /** + * Data structure that stores the actual user data set at a given + * slot. +@@ -70,9 +72,9 @@ struct DBusDataSlotList + int n_slots; /**< Slots we have storage for in data_slots */ + }; + +-dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator); ++dbus_bool_t _dbus_data_slot_allocator_init (DBusDataSlotAllocator *allocator, ++ DBusGlobalLock lock); + dbus_bool_t _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, +- DBusRMutex **mutex_loc, + int *slot_id_p); + void _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, + int *slot_id_p); +diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c +index 0e5d807..1a36734 100644 +--- a/dbus/dbus-internals.c ++++ b/dbus/dbus-internals.c +@@ -163,23 +163,6 @@ + */ + + /** +- * @def _DBUS_DEFINE_GLOBAL_LOCK +- * +- * Defines a global lock variable with the given name. +- * The lock must be added to the list to initialize +- * in dbus_threads_init(). +- */ +- +-/** +- * @def _DBUS_DECLARE_GLOBAL_LOCK +- * +- * Expands to declaration of a global lock defined +- * with _DBUS_DEFINE_GLOBAL_LOCK. +- * The lock must be added to the list to initialize +- * in dbus_threads_init(). +- */ +- +-/** + * @def _DBUS_LOCK + * + * Locks a global lock +@@ -847,7 +830,7 @@ _dbus_read_uuid_file (const DBusString *filename, + } + } + +-_DBUS_DEFINE_GLOBAL_LOCK (machine_uuid); ++/* Protected by _DBUS_LOCK (machine_uuid) */ + static int machine_uuid_initialized_generation = 0; + static DBusGUID machine_uuid; + +diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h +index 336d22e..22ad297 100644 +--- a/dbus/dbus-internals.h ++++ b/dbus/dbus-internals.h +@@ -297,35 +297,42 @@ dbus_bool_t _dbus_test_oom_handling (const char *description, + #endif /* !DBUS_BUILD_TESTS */ + + typedef void (* DBusShutdownFunction) (void *data); +-dbus_bool_t _dbus_register_shutdown_func (DBusShutdownFunction function, +- void *data); ++dbus_bool_t _dbus_register_shutdown_func (DBusShutdownFunction function, ++ void *data); ++dbus_bool_t _dbus_register_shutdown_func_unlocked (DBusShutdownFunction function, ++ void *data); + + extern int _dbus_current_generation; + +-/* Thread initializers */ +-#define _DBUS_LOCK_NAME(name) _dbus_lock_##name +-#define _DBUS_DECLARE_GLOBAL_LOCK(name) extern DBusRMutex *_dbus_lock_##name +-#define _DBUS_DEFINE_GLOBAL_LOCK(name) DBusRMutex *_dbus_lock_##name +-#define _DBUS_LOCK(name) _dbus_rmutex_lock (_dbus_lock_##name) +-#define _DBUS_UNLOCK(name) _dbus_rmutex_unlock (_dbus_lock_##name) +- +-/* index 0-4 */ +-_DBUS_DECLARE_GLOBAL_LOCK (list); +-_DBUS_DECLARE_GLOBAL_LOCK (connection_slots); +-_DBUS_DECLARE_GLOBAL_LOCK (pending_call_slots); +-_DBUS_DECLARE_GLOBAL_LOCK (server_slots); +-_DBUS_DECLARE_GLOBAL_LOCK (message_slots); +-/* index 5-9 */ +-_DBUS_DECLARE_GLOBAL_LOCK (bus); +-_DBUS_DECLARE_GLOBAL_LOCK (bus_datas); +-_DBUS_DECLARE_GLOBAL_LOCK (shutdown_funcs); +-_DBUS_DECLARE_GLOBAL_LOCK (system_users); +-_DBUS_DECLARE_GLOBAL_LOCK (message_cache); +-/* index 10-11 */ +-_DBUS_DECLARE_GLOBAL_LOCK (shared_connections); +-_DBUS_DECLARE_GLOBAL_LOCK (machine_uuid); +- +-#define _DBUS_N_GLOBAL_LOCKS (12) ++/* The weird case convention is to avoid having to change all the callers, ++ * which would be quite a mega-patch. */ ++typedef enum ++{ ++ /* index 0-4 */ ++ _DBUS_LOCK_list, ++ _DBUS_LOCK_connection_slots, ++ _DBUS_LOCK_pending_call_slots, ++ _DBUS_LOCK_server_slots, ++ _DBUS_LOCK_message_slots, ++ /* index 5-9 */ ++ _DBUS_LOCK_bus, ++ _DBUS_LOCK_bus_datas, ++ _DBUS_LOCK_shutdown_funcs, ++ _DBUS_LOCK_system_users, ++ _DBUS_LOCK_message_cache, ++ /* index 10-11 */ ++ _DBUS_LOCK_shared_connections, ++ _DBUS_LOCK_machine_uuid, ++ ++ _DBUS_N_GLOBAL_LOCKS ++} DBusGlobalLock; ++ ++void _dbus_lock (DBusGlobalLock lock); ++void _dbus_unlock (DBusGlobalLock lock); ++ ++#define _DBUS_LOCK_NAME(name) _DBUS_LOCK_##name ++#define _DBUS_LOCK(name) _dbus_lock (_DBUS_LOCK_##name) ++#define _DBUS_UNLOCK(name) _dbus_unlock (_DBUS_LOCK_##name) + + dbus_bool_t _dbus_threads_init_debug (void); + +diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c +index 7e11cc8..e5a4940 100644 +--- a/dbus/dbus-list.c ++++ b/dbus/dbus-list.c +@@ -35,8 +35,8 @@ + * Types and functions related to DBusList. + */ + ++/* Protected by _DBUS_LOCK (list) */ + static DBusMemPool *list_pool; +-_DBUS_DEFINE_GLOBAL_LOCK (list); + + /** + * @defgroup DBusListInternals Linked list implementation details +diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c +index 317e37e..a13b951 100644 +--- a/dbus/dbus-memory.c ++++ b/dbus/dbus-memory.c +@@ -795,7 +795,7 @@ struct ShutdownClosure + void *data; /**< Data for function */ + }; + +-_DBUS_DEFINE_GLOBAL_LOCK (shutdown_funcs); ++/* Protected by _DBUS_LOCK (shutdown_funcs) */ + static ShutdownClosure *registered_globals = NULL; + + /** +@@ -810,6 +810,18 @@ dbus_bool_t + _dbus_register_shutdown_func (DBusShutdownFunction func, + void *data) + { ++ dbus_bool_t ok; ++ ++ _DBUS_LOCK (shutdown_funcs); ++ ok = _dbus_register_shutdown_func_unlocked (func, data); ++ _DBUS_UNLOCK (shutdown_funcs); ++ return ok; ++} ++ ++dbus_bool_t ++_dbus_register_shutdown_func_unlocked (DBusShutdownFunction func, ++ void *data) ++{ + ShutdownClosure *c; + + c = dbus_new (ShutdownClosure, 1); +@@ -820,13 +832,9 @@ _dbus_register_shutdown_func (DBusShutdownFunction func, + c->func = func; + c->data = data; + +- _DBUS_LOCK (shutdown_funcs); +- + c->next = registered_globals; + registered_globals = c; + +- _DBUS_UNLOCK (shutdown_funcs); +- + return TRUE; + } + +diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c +index 71bcee6..2814569 100644 +--- a/dbus/dbus-message.c ++++ b/dbus/dbus-message.c +@@ -506,7 +506,7 @@ _dbus_message_set_signature (DBusMessage *message, + /** Avoid caching too many messages */ + #define MAX_MESSAGE_CACHE_SIZE 5 + +-_DBUS_DEFINE_GLOBAL_LOCK (message_cache); ++/* Protected by _DBUS_LOCK (message_cache) */ + static DBusMessage *message_cache[MAX_MESSAGE_CACHE_SIZE]; + static int message_cache_count = 0; + static dbus_bool_t message_cache_shutdown_registered = FALSE; +@@ -4423,8 +4423,8 @@ _dbus_message_loader_get_max_message_unix_fds (DBusMessageLoader *loader) + return loader->max_message_unix_fds; + } + +-static DBusDataSlotAllocator slot_allocator; +-_DBUS_DEFINE_GLOBAL_LOCK (message_slots); ++static DBusDataSlotAllocator slot_allocator = ++ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (message_slots)); + + /** + * Allocates an integer ID to be used for storing application-specific +@@ -4444,7 +4444,6 @@ dbus_bool_t + dbus_message_allocate_data_slot (dbus_int32_t *slot_p) + { + return _dbus_data_slot_allocator_alloc (&slot_allocator, +- &_DBUS_LOCK_NAME (message_slots), + slot_p); + } + +diff --git a/dbus/dbus-pending-call.c b/dbus/dbus-pending-call.c +index 62c6c74..1604408 100644 +--- a/dbus/dbus-pending-call.c ++++ b/dbus/dbus-pending-call.c +@@ -489,8 +489,8 @@ _dbus_pending_call_get_completed_unlocked (DBusPendingCall *pending) + return pending->completed; + } + +-static DBusDataSlotAllocator slot_allocator; +-_DBUS_DEFINE_GLOBAL_LOCK (pending_call_slots); ++static DBusDataSlotAllocator slot_allocator = ++ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (pending_call_slots)); + + /** + * Stores a pointer on a #DBusPendingCall, along +@@ -768,7 +768,6 @@ dbus_pending_call_allocate_data_slot (dbus_int32_t *slot_p) + _dbus_return_val_if_fail (slot_p != NULL, FALSE); + + return _dbus_data_slot_allocator_alloc (&slot_allocator, +- &_DBUS_LOCK_NAME (pending_call_slots), + slot_p); + } + +diff --git a/dbus/dbus-server.c b/dbus/dbus-server.c +index b62c2b4..e021266 100644 +--- a/dbus/dbus-server.c ++++ b/dbus/dbus-server.c +@@ -1071,9 +1071,8 @@ dbus_server_set_auth_mechanisms (DBusServer *server, + return TRUE; + } + +- +-static DBusDataSlotAllocator slot_allocator; +-_DBUS_DEFINE_GLOBAL_LOCK (server_slots); ++static DBusDataSlotAllocator slot_allocator = ++ _DBUS_DATA_SLOT_ALLOCATOR_INIT (_DBUS_LOCK_NAME (server_slots)); + + /** + * Allocates an integer ID to be used for storing application-specific +@@ -1093,7 +1092,6 @@ dbus_bool_t + dbus_server_allocate_data_slot (dbus_int32_t *slot_p) + { + return _dbus_data_slot_allocator_alloc (&slot_allocator, +- (DBusRMutex **)&_DBUS_LOCK_NAME (server_slots), + slot_p); + } + +diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c +index 4e14ac3..0fbf9e7 100644 +--- a/dbus/dbus-sysdeps.c ++++ b/dbus/dbus-sysdeps.c +@@ -46,8 +46,6 @@ + #include + #endif + +-_DBUS_DEFINE_GLOBAL_LOCK (system_users); +- + #ifdef DBUS_WIN + #include + #elif (defined __APPLE__) +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index 43676bc..297a7e4 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -343,23 +343,19 @@ _dbus_condvar_wake_one (DBusCondVar *cond) + _dbus_platform_condvar_wake_one (cond); + } + ++static DBusRMutex *global_locks[_DBUS_N_GLOBAL_LOCKS] = { NULL }; ++ + static void +-shutdown_global_locks (void *data) ++shutdown_global_locks (void *nil) + { +- DBusRMutex ***locks = data; + int i; + +- i = 0; +- while (i < _DBUS_N_GLOBAL_LOCKS) ++ for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++) + { +- if (*(locks[i]) != NULL) +- _dbus_platform_rmutex_free (*(locks[i])); +- +- *(locks[i]) = NULL; +- ++i; ++ _dbus_assert (global_locks[i] != NULL); ++ _dbus_platform_rmutex_free (global_locks[i]); ++ global_locks[i] = NULL; + } +- +- dbus_free (locks); + } + + static void +@@ -483,67 +479,60 @@ init_uninitialized_locks (void) + } + + static dbus_bool_t +-init_locks (void) ++init_global_locks (void) + { + int i; +- DBusRMutex ***dynamic_global_locks; +- DBusRMutex **global_locks[] = { +-#define LOCK_ADDR(name) (& _dbus_lock_##name) +- LOCK_ADDR (list), +- LOCK_ADDR (connection_slots), +- LOCK_ADDR (pending_call_slots), +- LOCK_ADDR (server_slots), +- LOCK_ADDR (message_slots), +- LOCK_ADDR (bus), +- LOCK_ADDR (bus_datas), +- LOCK_ADDR (shutdown_funcs), +- LOCK_ADDR (system_users), +- LOCK_ADDR (message_cache), +- LOCK_ADDR (shared_connections), +- LOCK_ADDR (machine_uuid) +-#undef LOCK_ADDR +- }; +- +- _DBUS_STATIC_ASSERT (_DBUS_N_ELEMENTS (global_locks) == _DBUS_N_GLOBAL_LOCKS); +- +- i = 0; +- +- dynamic_global_locks = dbus_new (DBusRMutex**, _DBUS_N_GLOBAL_LOCKS); +- if (dynamic_global_locks == NULL) +- goto failed; +- +- while (i < _DBUS_N_ELEMENTS (global_locks)) ++ dbus_bool_t ok; ++ ++ for (i = 0; i < _DBUS_N_GLOBAL_LOCKS; i++) + { +- *global_locks[i] = _dbus_platform_rmutex_new (); ++ _dbus_assert (global_locks[i] == NULL); ++ ++ global_locks[i] = _dbus_platform_rmutex_new (); + +- if (*global_locks[i] == NULL) ++ if (global_locks[i] == NULL) + goto failed; ++ } + +- dynamic_global_locks[i] = global_locks[i]; ++ _dbus_lock (_DBUS_LOCK_NAME (shutdown_funcs)); ++ ok = _dbus_register_shutdown_func_unlocked (shutdown_global_locks, NULL); ++ _dbus_unlock (_DBUS_LOCK_NAME (shutdown_funcs)); + +- ++i; +- } +- +- if (!_dbus_register_shutdown_func (shutdown_global_locks, +- dynamic_global_locks)) ++ if (!ok) + goto failed; + +- if (!init_uninitialized_locks ()) +- goto failed; +- + return TRUE; + + failed: +- dbus_free (dynamic_global_locks); +- + for (i = i - 1; i >= 0; i--) + { +- _dbus_platform_rmutex_free (*global_locks[i]); +- *global_locks[i] = NULL; ++ _dbus_platform_rmutex_free (global_locks[i]); ++ global_locks[i] = NULL; + } ++ + return FALSE; + } + ++void ++_dbus_lock (DBusGlobalLock lock) ++{ ++ _dbus_assert (lock >= 0); ++ _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); ++ ++ if (thread_init_generation == _dbus_current_generation) ++ _dbus_platform_rmutex_lock (global_locks[lock]); ++} ++ ++void ++_dbus_unlock (DBusGlobalLock lock) ++{ ++ _dbus_assert (lock >= 0); ++ _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); ++ ++ if (thread_init_generation == _dbus_current_generation) ++ _dbus_platform_rmutex_unlock (global_locks[lock]); ++} ++ + /** @} */ /* end of internals */ + + /** +@@ -587,7 +576,8 @@ dbus_threads_init (const DBusThreadFunctions *functions) + } + + if (!_dbus_threads_init_platform_specific() || +- !init_locks ()) ++ !init_global_locks () || ++ !init_uninitialized_locks ()) + { + _dbus_threads_unlock_platform_specific (); + return FALSE; diff --git a/recipes-core/dbus/files/0009-Make-taking-a-global-lock-automatically-initialize-l.patch b/recipes-core/dbus/files/0009-Make-taking-a-global-lock-automatically-initialize-l.patch new file mode 100644 index 0000000..d104bc4 --- /dev/null +++ b/recipes-core/dbus/files/0009-Make-taking-a-global-lock-automatically-initialize-l.patch @@ -0,0 +1,719 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 16:28:44 +0100 +Subject: Make taking a global lock automatically initialize locking if needed + +This lets them be thread-safe by default, at the cost that they can +now fail. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Anas Nashif +Applied-upstream: 1.7.6, commit:2b3272c75ae48c93911bd6f656965cf77d6de3e8 +Bug-Tizen: TZPC-1971 +Change-Id: I7e547e5776d37051ec8b6eccc2c8bd34b8d1996b +--- + bus/stats.c | 4 +-- + dbus/dbus-bus.c | 52 ++++++++++++++++++++++++++++++-------- + dbus/dbus-connection.c | 50 ++++++++++++++++++++++++++---------- + dbus/dbus-dataslot.c | 19 ++++++++++---- + dbus/dbus-internals.c | 8 ++++-- + dbus/dbus-internals.h | 4 +-- + dbus/dbus-list.c | 17 ++++++++++--- + dbus/dbus-memory.c | 4 ++- + dbus/dbus-message.c | 19 +++++++++++--- + dbus/dbus-threads.c | 28 +++++++++++++------- + dbus/dbus-userdb-util.c | 20 ++++++++++++--- + dbus/dbus-userdb.c | 43 +++++++++++++++++++++++-------- + dbus/dbus-userdb.h | 2 +- + test/name-test/test-threads-init.c | 14 ++++++---- + 14 files changed, 213 insertions(+), 71 deletions(-) + +diff --git a/bus/stats.c b/bus/stats.c +index 28fd49b..4553191 100644 +--- a/bus/stats.c ++++ b/bus/stats.c +@@ -203,8 +203,8 @@ bus_stats_handle_get_stats (DBusConnection *connection, + if (!asv_add_uint32 (&iter, &arr_iter, "Serial", stats_serial++)) + goto oom; + +- _dbus_list_get_stats (&in_use, &in_free_list, &allocated); +- if (!asv_add_uint32 (&iter, &arr_iter, "ListMemPoolUsedBytes", in_use) || ++ if (!_dbus_list_get_stats (&in_use, &in_free_list, &allocated) || ++ !asv_add_uint32 (&iter, &arr_iter, "ListMemPoolUsedBytes", in_use) || + !asv_add_uint32 (&iter, &arr_iter, "ListMemPoolCachedBytes", + in_free_list) || + !asv_add_uint32 (&iter, &arr_iter, "ListMemPoolAllocatedBytes", +diff --git a/dbus/dbus-bus.c b/dbus/dbus-bus.c +index 7a31cbd..3aa5c09 100644 +--- a/dbus/dbus-bus.c ++++ b/dbus/dbus-bus.c +@@ -317,7 +317,11 @@ bus_data_free (void *data) + if (bd->is_well_known) + { + int i; +- _DBUS_LOCK (bus); ++ ++ if (!_DBUS_LOCK (bus)) ++ _dbus_assert_not_reached ("global locks should have been initialized " ++ "when we attached bus data"); ++ + /* We may be stored in more than one slot */ + /* This should now be impossible - these slots are supposed to + * be cleared on disconnect, so should not need to be cleared on +@@ -388,8 +392,13 @@ void + _dbus_bus_notify_shared_connection_disconnected_unlocked (DBusConnection *connection) + { + int i; +- +- _DBUS_LOCK (bus); ++ ++ if (!_DBUS_LOCK (bus)) ++ { ++ /* If it was in bus_connections, we would have initialized global locks ++ * when we added it. So, it can't be. */ ++ return; ++ } + + /* We are expecting to have the connection saved in only one of these + * slots, but someone could in a pathological case set system and session +@@ -423,7 +432,12 @@ internal_bus_get (DBusBusType type, + + connection = NULL; + +- _DBUS_LOCK (bus); ++ if (!_DBUS_LOCK (bus)) ++ { ++ _DBUS_SET_OOM (error); ++ /* do not "goto out", that would try to unlock */ ++ return NULL; ++ } + + if (!init_connections_unlocked ()) + { +@@ -493,8 +507,10 @@ internal_bus_get (DBusBusType type, + */ + dbus_connection_set_exit_on_disconnect (connection, + TRUE); +- +- _DBUS_LOCK (bus_datas); ++ ++ if (!_DBUS_LOCK (bus_datas)) ++ _dbus_assert_not_reached ("global locks were initialized already"); ++ + bd = ensure_bus_data (connection); + _dbus_assert (bd != NULL); /* it should have been created on + register, so OOM not possible */ +@@ -647,7 +663,12 @@ dbus_bus_register (DBusConnection *connection, + message = NULL; + reply = NULL; + +- _DBUS_LOCK (bus_datas); ++ if (!_DBUS_LOCK (bus_datas)) ++ { ++ _DBUS_SET_OOM (error); ++ /* do not "goto out", that would try to unlock */ ++ return FALSE; ++ } + + bd = ensure_bus_data (connection); + if (bd == NULL) +@@ -756,8 +777,12 @@ dbus_bus_set_unique_name (DBusConnection *connection, + _dbus_return_val_if_fail (connection != NULL, FALSE); + _dbus_return_val_if_fail (unique_name != NULL, FALSE); + +- _DBUS_LOCK (bus_datas); +- ++ if (!_DBUS_LOCK (bus_datas)) ++ { ++ /* do not "goto out", that would try to unlock */ ++ return FALSE; ++ } ++ + bd = ensure_bus_data (connection); + if (bd == NULL) + goto out; +@@ -799,8 +824,13 @@ dbus_bus_get_unique_name (DBusConnection *connection) + + _dbus_return_val_if_fail (connection != NULL, NULL); + +- _DBUS_LOCK (bus_datas); +- ++ if (!_DBUS_LOCK (bus_datas)) ++ { ++ /* We'd have initialized locks when we gave it its unique name, if it ++ * had one. Don't "goto out", that would try to unlock. */ ++ return NULL; ++ } ++ + bd = ensure_bus_data (connection); + if (bd == NULL) + goto out; +diff --git a/dbus/dbus-connection.c b/dbus/dbus-connection.c +index 03ee066..87cfeb0 100644 +--- a/dbus/dbus-connection.c ++++ b/dbus/dbus-connection.c +@@ -1555,9 +1555,14 @@ static void + shared_connections_shutdown (void *data) + { + int n_entries; +- +- _DBUS_LOCK (shared_connections); +- ++ ++ if (!_DBUS_LOCK (shared_connections)) ++ { ++ /* We'd have initialized locks before adding anything, so there ++ * can't be anything there. */ ++ return; ++ } ++ + /* This is a little bit unpleasant... better ideas? */ + while ((n_entries = _dbus_hash_table_get_n_entries (shared_connections)) > 0) + { +@@ -1571,7 +1576,8 @@ shared_connections_shutdown (void *data) + + _DBUS_UNLOCK (shared_connections); + close_connection_on_shutdown (connection); +- _DBUS_LOCK (shared_connections); ++ if (!_DBUS_LOCK (shared_connections)) ++ _dbus_assert_not_reached ("global locks were already initialized"); + + /* The connection should now be dead and not in our hash ... */ + _dbus_assert (_dbus_hash_table_get_n_entries (shared_connections) < n_entries); +@@ -1590,7 +1596,8 @@ shared_connections_shutdown (void *data) + { + _DBUS_UNLOCK (shared_connections); + close_connection_on_shutdown (connection); +- _DBUS_LOCK (shared_connections); ++ if (!_DBUS_LOCK (shared_connections)) ++ _dbus_assert_not_reached ("global locks were already initialized"); + connection = _dbus_list_pop_first (&shared_connections_no_guid); + } + } +@@ -1607,8 +1614,13 @@ connection_lookup_shared (DBusAddressEntry *entry, + _dbus_verbose ("checking for existing connection\n"); + + *result = NULL; +- +- _DBUS_LOCK (shared_connections); ++ ++ if (!_DBUS_LOCK (shared_connections)) ++ { ++ /* If it was shared, we'd have initialized global locks when we put ++ * it in shared_connections. */ ++ return FALSE; ++ } + + if (shared_connections == NULL) + { +@@ -1706,7 +1718,8 @@ connection_record_shared_unlocked (DBusConnection *connection, + + if (guid == NULL) + { +- _DBUS_LOCK (shared_connections); ++ if (!_DBUS_LOCK (shared_connections)) ++ return FALSE; + + if (!_dbus_list_prepend (&shared_connections_no_guid, connection)) + { +@@ -1733,8 +1746,14 @@ connection_record_shared_unlocked (DBusConnection *connection, + dbus_free (guid_key); + return FALSE; + } +- +- _DBUS_LOCK (shared_connections); ++ ++ if (!_DBUS_LOCK (shared_connections)) ++ { ++ dbus_free (guid_in_connection); ++ dbus_free (guid_key); ++ return FALSE; ++ } ++ + _dbus_assert (shared_connections != NULL); + + if (!_dbus_hash_table_insert_string (shared_connections, +@@ -1765,9 +1784,14 @@ connection_forget_shared_unlocked (DBusConnection *connection) + + if (!connection->shareable) + return; +- +- _DBUS_LOCK (shared_connections); +- ++ ++ if (!_DBUS_LOCK (shared_connections)) ++ { ++ /* If it was shared, we'd have initialized global locks when we put ++ * it in the table; so it can't be there. */ ++ return; ++ } ++ + if (connection->server_guid != NULL) + { + _dbus_verbose ("dropping connection to %s out of the shared table\n", +diff --git a/dbus/dbus-dataslot.c b/dbus/dbus-dataslot.c +index b3c8090..412e7f4 100644 +--- a/dbus/dbus-dataslot.c ++++ b/dbus/dbus-dataslot.c +@@ -71,7 +71,8 @@ _dbus_data_slot_allocator_alloc (DBusDataSlotAllocator *allocator, + { + dbus_int32_t slot; + +- _dbus_lock (allocator->lock); ++ if (!_dbus_lock (allocator->lock)) ++ return FALSE; + + if (*slot_id_p >= 0) + { +@@ -153,8 +154,10 @@ void + _dbus_data_slot_allocator_free (DBusDataSlotAllocator *allocator, + dbus_int32_t *slot_id_p) + { +- _dbus_lock (allocator->lock); +- ++ if (!_dbus_lock (allocator->lock)) ++ _dbus_assert_not_reached ("we should have initialized global locks " ++ "before we allocated this slot"); ++ + _dbus_assert (*slot_id_p < allocator->n_allocated_slots); + _dbus_assert (allocator->allocated_slots[*slot_id_p].slot_id == *slot_id_p); + _dbus_assert (allocator->allocated_slots[*slot_id_p].refcount > 0); +@@ -228,7 +231,10 @@ _dbus_data_slot_list_set (DBusDataSlotAllocator *allocator, + * be e.g. realloc()ing allocated_slots. We avoid doing this if asserts + * are disabled, since then the asserts are empty. + */ +- _dbus_lock (allocator->lock); ++ if (!_dbus_lock (allocator->lock)) ++ _dbus_assert_not_reached ("we should have initialized global locks " ++ "before we allocated this slot"); ++ + _dbus_assert (slot < allocator->n_allocated_slots); + _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); + _dbus_unlock (allocator->lock); +@@ -285,7 +291,10 @@ _dbus_data_slot_list_get (DBusDataSlotAllocator *allocator, + * be e.g. realloc()ing allocated_slots. We avoid doing this if asserts + * are disabled, since then the asserts are empty. + */ +- _dbus_lock (allocator->lock); ++ if (!_dbus_lock (allocator->lock)) ++ _dbus_assert_not_reached ("we should have initialized global locks " ++ "before we allocated this slot"); ++ + _dbus_assert (slot >= 0); + _dbus_assert (slot < allocator->n_allocated_slots); + _dbus_assert (allocator->allocated_slots[slot].slot_id == slot); +diff --git a/dbus/dbus-internals.c b/dbus/dbus-internals.c +index 1a36734..63559be 100644 +--- a/dbus/dbus-internals.c ++++ b/dbus/dbus-internals.c +@@ -165,7 +165,9 @@ + /** + * @def _DBUS_LOCK + * +- * Locks a global lock ++ * Locks a global lock, initializing it first if necessary. ++ * ++ * @returns #FALSE if not enough memory + */ + + /** +@@ -849,7 +851,9 @@ _dbus_get_local_machine_uuid_encoded (DBusString *uuid_str) + { + dbus_bool_t ok; + +- _DBUS_LOCK (machine_uuid); ++ if (!_DBUS_LOCK (machine_uuid)) ++ return FALSE; ++ + if (machine_uuid_initialized_generation != _dbus_current_generation) + { + DBusError error = DBUS_ERROR_INIT; +diff --git a/dbus/dbus-internals.h b/dbus/dbus-internals.h +index 22ad297..edde80b 100644 +--- a/dbus/dbus-internals.h ++++ b/dbus/dbus-internals.h +@@ -327,8 +327,8 @@ typedef enum + _DBUS_N_GLOBAL_LOCKS + } DBusGlobalLock; + +-void _dbus_lock (DBusGlobalLock lock); +-void _dbus_unlock (DBusGlobalLock lock); ++dbus_bool_t _dbus_lock (DBusGlobalLock lock) _DBUS_GNUC_WARN_UNUSED_RESULT; ++void _dbus_unlock (DBusGlobalLock lock); + + #define _DBUS_LOCK_NAME(name) _DBUS_LOCK_##name + #define _DBUS_LOCK(name) _dbus_lock (_DBUS_LOCK_##name) +diff --git a/dbus/dbus-list.c b/dbus/dbus-list.c +index e5a4940..525e067 100644 +--- a/dbus/dbus-list.c ++++ b/dbus/dbus-list.c +@@ -56,7 +56,8 @@ alloc_link (void *data) + { + DBusList *link; + +- _DBUS_LOCK (list); ++ if (!_DBUS_LOCK (list)) ++ return FALSE; + + if (list_pool == NULL) + { +@@ -93,7 +94,10 @@ alloc_link (void *data) + static void + free_link (DBusList *link) + { +- _DBUS_LOCK (list); ++ if (!_DBUS_LOCK (list)) ++ _dbus_assert_not_reached ("we should have initialized global locks " ++ "before we allocated a linked-list link"); ++ + if (_dbus_mem_pool_dealloc (list_pool, link)) + { + _dbus_mem_pool_free (list_pool); +@@ -152,7 +156,14 @@ _dbus_list_get_stats (dbus_uint32_t *in_use_p, + dbus_uint32_t *in_free_list_p, + dbus_uint32_t *allocated_p) + { +- _DBUS_LOCK (list); ++ if (!_DBUS_LOCK (list)) ++ { ++ *in_use_p = 0; ++ *in_free_list_p = 0; ++ *allocated_p = 0; ++ return; ++ } ++ + _dbus_mem_pool_get_stats (list_pool, in_use_p, in_free_list_p, allocated_p); + _DBUS_UNLOCK (list); + } +diff --git a/dbus/dbus-memory.c b/dbus/dbus-memory.c +index a13b951..6cf0449 100644 +--- a/dbus/dbus-memory.c ++++ b/dbus/dbus-memory.c +@@ -812,7 +812,9 @@ _dbus_register_shutdown_func (DBusShutdownFunction func, + { + dbus_bool_t ok; + +- _DBUS_LOCK (shutdown_funcs); ++ if (!_DBUS_LOCK (shutdown_funcs)) ++ return FALSE; ++ + ok = _dbus_register_shutdown_func_unlocked (func, data); + _DBUS_UNLOCK (shutdown_funcs); + return ok; +diff --git a/dbus/dbus-message.c b/dbus/dbus-message.c +index 2814569..275c425 100644 +--- a/dbus/dbus-message.c ++++ b/dbus/dbus-message.c +@@ -516,7 +516,9 @@ dbus_message_cache_shutdown (void *data) + { + int i; + +- _DBUS_LOCK (message_cache); ++ if (!_DBUS_LOCK (message_cache)) ++ _dbus_assert_not_reached ("we would have initialized global locks " ++ "before registering a shutdown function"); + + i = 0; + while (i < MAX_MESSAGE_CACHE_SIZE) +@@ -548,7 +550,12 @@ dbus_message_get_cached (void) + + message = NULL; + +- _DBUS_LOCK (message_cache); ++ if (!_DBUS_LOCK (message_cache)) ++ { ++ /* we'd have initialized global locks before caching anything, ++ * so there can't be anything in the cache */ ++ return NULL; ++ } + + _dbus_assert (message_cache_count >= 0); + +@@ -660,7 +667,13 @@ dbus_message_cache_or_finalize (DBusMessage *message) + + was_cached = FALSE; + +- _DBUS_LOCK (message_cache); ++ if (!_DBUS_LOCK (message_cache)) ++ { ++ /* The only way to get a non-null message goes through ++ * dbus_message_get_cached() which takes the lock. */ ++ _dbus_assert_not_reached ("we would have initialized global locks " ++ "the first time we constructed a message"); ++ } + + if (!message_cache_shutdown_registered) + { +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index 297a7e4..2c2a816 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -366,10 +366,12 @@ shutdown_uninitialized_locks (void *data) + _dbus_list_clear (&uninitialized_condvar_list); + } + ++/* init_global_locks() must be called first. */ + static dbus_bool_t + init_uninitialized_locks (void) + { + DBusList *link; ++ dbus_bool_t ok; + + _dbus_assert (thread_init_generation != _dbus_current_generation); + +@@ -422,8 +424,12 @@ init_uninitialized_locks (void) + _dbus_list_clear (&uninitialized_cmutex_list); + _dbus_list_clear (&uninitialized_condvar_list); + +- if (!_dbus_register_shutdown_func (shutdown_uninitialized_locks, +- NULL)) ++ /* This assumes that init_global_locks() has already been called. */ ++ _dbus_platform_rmutex_lock (global_locks[_DBUS_LOCK_shutdown_funcs]); ++ ok = _dbus_register_shutdown_func_unlocked (shutdown_uninitialized_locks, NULL); ++ _dbus_platform_rmutex_unlock (global_locks[_DBUS_LOCK_shutdown_funcs]); ++ ++ if (!ok) + goto fail_condvar; + + return TRUE; +@@ -494,9 +500,9 @@ init_global_locks (void) + goto failed; + } + +- _dbus_lock (_DBUS_LOCK_NAME (shutdown_funcs)); ++ _dbus_platform_rmutex_lock (global_locks[_DBUS_LOCK_shutdown_funcs]); + ok = _dbus_register_shutdown_func_unlocked (shutdown_global_locks, NULL); +- _dbus_unlock (_DBUS_LOCK_NAME (shutdown_funcs)); ++ _dbus_platform_rmutex_unlock (global_locks[_DBUS_LOCK_shutdown_funcs]); + + if (!ok) + goto failed; +@@ -513,14 +519,18 @@ init_global_locks (void) + return FALSE; + } + +-void ++dbus_bool_t + _dbus_lock (DBusGlobalLock lock) + { + _dbus_assert (lock >= 0); + _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); + +- if (thread_init_generation == _dbus_current_generation) +- _dbus_platform_rmutex_lock (global_locks[lock]); ++ if (thread_init_generation != _dbus_current_generation && ++ !dbus_threads_init_default ()) ++ return FALSE; ++ ++ _dbus_platform_rmutex_lock (global_locks[lock]); ++ return TRUE; + } + + void +@@ -529,8 +539,7 @@ _dbus_unlock (DBusGlobalLock lock) + _dbus_assert (lock >= 0); + _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); + +- if (thread_init_generation == _dbus_current_generation) +- _dbus_platform_rmutex_unlock (global_locks[lock]); ++ _dbus_platform_rmutex_unlock (global_locks[lock]); + } + + /** @} */ /* end of internals */ +@@ -576,6 +585,7 @@ dbus_threads_init (const DBusThreadFunctions *functions) + } + + if (!_dbus_threads_init_platform_specific() || ++ /* init_global_locks() must be called before init_uninitialized_locks. */ + !init_global_locks () || + !init_uninitialized_locks ()) + { +diff --git a/dbus/dbus-userdb-util.c b/dbus/dbus-userdb-util.c +index 16bf229..a8cc3d1 100644 +--- a/dbus/dbus-userdb-util.c ++++ b/dbus/dbus-userdb-util.c +@@ -103,7 +103,11 @@ _dbus_is_console_user (dbus_uid_t uid, + + #endif /* HAVE_CONSOLE_OWNER_FILE */ + +- _dbus_user_database_lock_system (); ++ if (!_dbus_user_database_lock_system ()) ++ { ++ _DBUS_SET_OOM (error); ++ return FALSE; ++ } + + db = _dbus_user_database_get_system (); + if (db == NULL) +@@ -157,7 +161,10 @@ _dbus_get_group_id (const DBusString *groupname, + { + DBusUserDatabase *db; + const DBusGroupInfo *info; +- _dbus_user_database_lock_system (); ++ ++ /* FIXME: this can't distinguish ENOMEM from other errors */ ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; + + db = _dbus_user_database_get_system (); + if (db == NULL) +@@ -194,7 +201,10 @@ _dbus_get_user_id_and_primary_group (const DBusString *username, + { + DBusUserDatabase *db; + const DBusUserInfo *info; +- _dbus_user_database_lock_system (); ++ ++ /* FIXME: this can't distinguish ENOMEM from other errors */ ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; + + db = _dbus_user_database_get_system (); + if (db == NULL) +@@ -387,7 +397,9 @@ _dbus_groups_from_uid (dbus_uid_t uid, + *group_ids = NULL; + *n_group_ids = 0; + +- _dbus_user_database_lock_system (); ++ /* FIXME: this can't distinguish ENOMEM from other errors */ ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; + + db = _dbus_user_database_get_system (); + if (db == NULL) +diff --git a/dbus/dbus-userdb.c b/dbus/dbus-userdb.c +index 4e8b39a..73f8fce 100644 +--- a/dbus/dbus-userdb.c ++++ b/dbus/dbus-userdb.c +@@ -306,11 +306,18 @@ init_system_db (void) + /** + * Locks global system user database. + */ +-void ++dbus_bool_t + _dbus_user_database_lock_system (void) + { +- _DBUS_LOCK (system_users); +- database_locked = TRUE; ++ if (_DBUS_LOCK (system_users)) ++ { ++ database_locked = TRUE; ++ return TRUE; ++ } ++ else ++ { ++ return FALSE; ++ } + } + + /** +@@ -345,8 +352,12 @@ _dbus_user_database_get_system (void) + void + _dbus_user_database_flush_system (void) + { +- _dbus_user_database_lock_system (); +- ++ if (!_dbus_user_database_lock_system ()) ++ { ++ /* nothing to flush */ ++ return; ++ } ++ + if (system_db != NULL) + _dbus_user_database_flush (system_db); + +@@ -363,7 +374,9 @@ _dbus_user_database_flush_system (void) + dbus_bool_t + _dbus_username_from_current_process (const DBusString **username) + { +- _dbus_user_database_lock_system (); ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; ++ + if (!init_system_db ()) + { + _dbus_user_database_unlock_system (); +@@ -385,7 +398,9 @@ _dbus_username_from_current_process (const DBusString **username) + dbus_bool_t + _dbus_homedir_from_current_process (const DBusString **homedir) + { +- _dbus_user_database_lock_system (); ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; ++ + if (!init_system_db ()) + { + _dbus_user_database_unlock_system (); +@@ -410,7 +425,10 @@ _dbus_homedir_from_username (const DBusString *username, + { + DBusUserDatabase *db; + const DBusUserInfo *info; +- _dbus_user_database_lock_system (); ++ ++ /* FIXME: this can't distinguish ENOMEM from other errors */ ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; + + db = _dbus_user_database_get_system (); + if (db == NULL) +@@ -449,7 +467,10 @@ _dbus_homedir_from_uid (dbus_uid_t uid, + { + DBusUserDatabase *db; + const DBusUserInfo *info; +- _dbus_user_database_lock_system (); ++ ++ /* FIXME: this can't distinguish ENOMEM from other errors */ ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; + + db = _dbus_user_database_get_system (); + if (db == NULL) +@@ -496,7 +517,9 @@ _dbus_credentials_add_from_user (DBusCredentials *credentials, + DBusUserDatabase *db; + const DBusUserInfo *info; + +- _dbus_user_database_lock_system (); ++ /* FIXME: this can't distinguish ENOMEM from other errors */ ++ if (!_dbus_user_database_lock_system ()) ++ return FALSE; + + db = _dbus_user_database_get_system (); + if (db == NULL) +diff --git a/dbus/dbus-userdb.h b/dbus/dbus-userdb.h +index cb49d9e..d6b72d8 100644 +--- a/dbus/dbus-userdb.h ++++ b/dbus/dbus-userdb.h +@@ -86,7 +86,7 @@ void _dbus_group_info_free_allocated (DBusGroupInfo *info); + #endif /* DBUS_USERDB_INCLUDES_PRIVATE */ + + DBusUserDatabase* _dbus_user_database_get_system (void); +-void _dbus_user_database_lock_system (void); ++dbus_bool_t _dbus_user_database_lock_system (void) _DBUS_GNUC_WARN_UNUSED_RESULT; + void _dbus_user_database_unlock_system (void); + void _dbus_user_database_flush_system (void); + +diff --git a/test/name-test/test-threads-init.c b/test/name-test/test-threads-init.c +index 5e22852..580ffe1 100644 +--- a/test/name-test/test-threads-init.c ++++ b/test/name-test/test-threads-init.c +@@ -149,11 +149,15 @@ main (int argc, char *argv[]) + &dispatch_cond1, + &io_path_cond1); + +- check_mutex_lock (mutex1, mutex2, FALSE); +- check_mutex_lock (dispatch_mutex1, dispatch_mutex2, FALSE); +- check_mutex_lock (io_path_mutex1, io_path_mutex2, FALSE); +- check_condvar_lock (dispatch_cond1, dispatch_cond2, FALSE); +- check_condvar_lock (io_path_cond1, io_path_cond2, FALSE); ++ /* Since 1.7 it is no longer the case that mutex1 != mutex2, because ++ * initializing global locks automatically initializes locks ++ * in general. However, it is true that the mutex is not the dummy ++ * implementation, which is what we really wanted to check here. */ ++ _dbus_assert (mutex1 != (DBusMutex *) 0xABCDEF); ++ _dbus_assert (dispatch_mutex1 != (DBusMutex *) 0xABCDEF); ++ _dbus_assert (dispatch_cond1 != (DBusCondVar *) 0xABCDEF2); ++ _dbus_assert (io_path_mutex1 != (DBusMutex *) 0xABCDEF); ++ _dbus_assert (io_path_cond1 != (DBusCondVar *) 0xABCDEF2); + + _run_iteration (conn); + _dbus_connection_test_get_locks (conn, &mutex2, diff --git a/recipes-core/dbus/files/0010-Always-initialize-threading-before-allocating-a-dyna.patch b/recipes-core/dbus/files/0010-Always-initialize-threading-before-allocating-a-dyna.patch new file mode 100644 index 0000000..e9abe9c --- /dev/null +++ b/recipes-core/dbus/files/0010-Always-initialize-threading-before-allocating-a-dyna.patch @@ -0,0 +1,491 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 16:37:51 +0100 +Subject: Always initialize threading before allocating a dynamic mutex + +Dynamic allocation of mutexes can fail anyway, so this is easy. + +Justification for not keeping the dummy mutex code-paths, even as an +opt-in thing for processes known to be high-performance and +single-threaded: real mutexes only cut the throughput of +test/dbus-daemon.c by a couple of percent on my laptop (from around +6700 to around 6600 messages per second), and libdbus crashes caused +by not calling dbus_threads_init_default() are sufficiently widespread +that they're wasting a lot of everyone's time. + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Anas Nashif +Bug-Tizen: TZPC-1971 +Applied-upstream: 1.7.6, commit:08391b14616c248458e838691d068aa48dc70d18 +Change-Id: I62e4fc541f6868ef44dc0654337b895e5392c16e +--- + dbus/dbus-threads.c | 300 ++++++++++------------------------------------------ + 1 file changed, 56 insertions(+), 244 deletions(-) + +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index 2c2a816..29462eb 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -27,18 +27,6 @@ + #include "dbus-list.h" + + static int thread_init_generation = 0; +- +-static DBusList *uninitialized_rmutex_list = NULL; +-static DBusList *uninitialized_cmutex_list = NULL; +-static DBusList *uninitialized_condvar_list = NULL; +- +-/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */ +-#define _DBUS_DUMMY_MUTEX ((DBusMutex*)0xABCDEF) +-#define _DBUS_DUMMY_RMUTEX ((DBusRMutex *) _DBUS_DUMMY_MUTEX) +-#define _DBUS_DUMMY_CMUTEX ((DBusCMutex *) _DBUS_DUMMY_MUTEX) +- +-/** This is used for the no-op default mutex pointer, just to be distinct from #NULL */ +-#define _DBUS_DUMMY_CONDVAR ((DBusCondVar*)0xABCDEF2) + + /** + * @defgroup DBusThreadsInternals Thread functions +@@ -59,11 +47,6 @@ static DBusList *uninitialized_condvar_list = NULL; + * If possible, the mutex returned by this function is recursive, to + * avoid deadlocks. However, that cannot be relied on. + * +- * The extra level of indirection given by allocating a pointer +- * to point to the mutex location allows the threading +- * module to swap out dummy mutexes for a real mutex so libraries +- * can initialize threads even after the D-Bus API has been used. +- * + * @param location_p the location of the new mutex, can return #NULL on OOM + */ + void +@@ -71,17 +54,13 @@ _dbus_rmutex_new_at_location (DBusRMutex **location_p) + { + _dbus_assert (location_p != NULL); + +- if (thread_init_generation == _dbus_current_generation) ++ if (!dbus_threads_init_default ()) + { +- *location_p = _dbus_platform_rmutex_new (); ++ *location_p = NULL; ++ return; + } +- else +- { +- *location_p = _DBUS_DUMMY_RMUTEX; + +- if (!_dbus_list_append (&uninitialized_rmutex_list, location_p)) +- *location_p = NULL; +- } ++ *location_p = _dbus_platform_rmutex_new (); + } + + /** +@@ -92,11 +71,6 @@ _dbus_rmutex_new_at_location (DBusRMutex **location_p) + * + * The returned mutex is suitable for use with condition variables. + * +- * The extra level of indirection given by allocating a pointer +- * to point to the mutex location allows the threading +- * module to swap out dummy mutexes for a real mutex so libraries +- * can initialize threads even after the D-Bus API has been used. +- * + * @param location_p the location of the new mutex, can return #NULL on OOM + */ + void +@@ -104,22 +78,17 @@ _dbus_cmutex_new_at_location (DBusCMutex **location_p) + { + _dbus_assert (location_p != NULL); + +- if (thread_init_generation == _dbus_current_generation) ++ if (!dbus_threads_init_default ()) + { +- *location_p = _dbus_platform_cmutex_new (); ++ *location_p = NULL; ++ return; + } +- else +- { +- *location_p = _DBUS_DUMMY_CMUTEX; + +- if (!_dbus_list_append (&uninitialized_cmutex_list, location_p)) +- *location_p = NULL; +- } ++ *location_p = _dbus_platform_cmutex_new (); + } + + /** +- * Frees a DBusRMutex or removes it from the uninitialized mutex list; +- * does nothing if passed a #NULL pointer. ++ * Frees a DBusRMutex; does nothing if passed a #NULL pointer. + */ + void + _dbus_rmutex_free_at_location (DBusRMutex **location_p) +@@ -127,23 +96,12 @@ _dbus_rmutex_free_at_location (DBusRMutex **location_p) + if (location_p == NULL) + return; + +- if (thread_init_generation == _dbus_current_generation) +- { +- if (*location_p != NULL) +- _dbus_platform_rmutex_free (*location_p); +- } +- else +- { +- _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_RMUTEX); +- +- _dbus_list_remove (&uninitialized_rmutex_list, location_p); +- } ++ if (*location_p != NULL) ++ _dbus_platform_rmutex_free (*location_p); + } + + /** +- * Frees a DBusCMutex and removes it from the +- * uninitialized mutex list; +- * does nothing if passed a #NULL pointer. ++ * Frees a DBusCMutex; does nothing if passed a #NULL pointer. + */ + void + _dbus_cmutex_free_at_location (DBusCMutex **location_p) +@@ -151,17 +109,8 @@ _dbus_cmutex_free_at_location (DBusCMutex **location_p) + if (location_p == NULL) + return; + +- if (thread_init_generation == _dbus_current_generation) +- { +- if (*location_p != NULL) +- _dbus_platform_cmutex_free (*location_p); +- } +- else +- { +- _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_CMUTEX); +- +- _dbus_list_remove (&uninitialized_cmutex_list, location_p); +- } ++ if (*location_p != NULL) ++ _dbus_platform_cmutex_free (*location_p); + } + + /** +@@ -172,8 +121,10 @@ _dbus_cmutex_free_at_location (DBusCMutex **location_p) + void + _dbus_rmutex_lock (DBusRMutex *mutex) + { +- if (mutex && thread_init_generation == _dbus_current_generation) +- _dbus_platform_rmutex_lock (mutex); ++ if (mutex == NULL) ++ return; ++ ++ _dbus_platform_rmutex_lock (mutex); + } + + /** +@@ -184,8 +135,10 @@ _dbus_rmutex_lock (DBusRMutex *mutex) + void + _dbus_cmutex_lock (DBusCMutex *mutex) + { +- if (mutex && thread_init_generation == _dbus_current_generation) +- _dbus_platform_cmutex_lock (mutex); ++ if (mutex == NULL) ++ return; ++ ++ _dbus_platform_cmutex_lock (mutex); + } + + /** +@@ -196,8 +149,10 @@ _dbus_cmutex_lock (DBusCMutex *mutex) + void + _dbus_rmutex_unlock (DBusRMutex *mutex) + { +- if (mutex && thread_init_generation == _dbus_current_generation) +- _dbus_platform_rmutex_unlock (mutex); ++ if (mutex == NULL) ++ return; ++ ++ _dbus_platform_rmutex_unlock (mutex); + } + + /** +@@ -208,8 +163,10 @@ _dbus_rmutex_unlock (DBusRMutex *mutex) + void + _dbus_cmutex_unlock (DBusCMutex *mutex) + { +- if (mutex && thread_init_generation == _dbus_current_generation) +- _dbus_platform_cmutex_unlock (mutex); ++ if (mutex == NULL) ++ return; ++ ++ _dbus_platform_cmutex_unlock (mutex); + } + + /** +@@ -223,19 +180,17 @@ _dbus_cmutex_unlock (DBusCMutex *mutex) + DBusCondVar * + _dbus_condvar_new (void) + { +- if (thread_init_generation == _dbus_current_generation) +- return _dbus_platform_condvar_new (); +- else +- return _DBUS_DUMMY_CONDVAR; ++ if (!dbus_threads_init_default ()) ++ return NULL; ++ ++ return _dbus_platform_condvar_new (); + } + + + /** + * This does the same thing as _dbus_condvar_new. It however + * gives another level of indirection by allocating a pointer +- * to point to the condvar location. This allows the threading +- * module to swap out dummy condvars for a real condvar so libraries +- * can initialize threads even after the D-Bus API has been used. ++ * to point to the condvar location; this used to be useful. + * + * @returns the location of a new condvar or #NULL on OOM + */ +@@ -245,17 +200,7 @@ _dbus_condvar_new_at_location (DBusCondVar **location_p) + { + _dbus_assert (location_p != NULL); + +- if (thread_init_generation == _dbus_current_generation) +- { +- *location_p = _dbus_condvar_new(); +- } +- else +- { +- *location_p = _DBUS_DUMMY_CONDVAR; +- +- if (!_dbus_list_append (&uninitialized_condvar_list, location_p)) +- *location_p = NULL; +- } ++ *location_p = _dbus_condvar_new(); + } + + +@@ -266,14 +211,14 @@ _dbus_condvar_new_at_location (DBusCondVar **location_p) + void + _dbus_condvar_free (DBusCondVar *cond) + { +- if (cond && thread_init_generation == _dbus_current_generation) +- _dbus_platform_condvar_free (cond); ++ if (cond == NULL) ++ return; ++ ++ _dbus_platform_condvar_free (cond); + } + + /** +- * Frees a conditional variable and removes it from the +- * uninitialized_condvar_list; +- * does nothing if passed a #NULL pointer. ++ * Frees a condition variable; does nothing if passed a #NULL pointer. + */ + void + _dbus_condvar_free_at_location (DBusCondVar **location_p) +@@ -281,17 +226,8 @@ _dbus_condvar_free_at_location (DBusCondVar **location_p) + if (location_p == NULL) + return; + +- if (thread_init_generation == _dbus_current_generation) +- { +- if (*location_p != NULL) +- _dbus_platform_condvar_free (*location_p); +- } +- else +- { +- _dbus_assert (*location_p == NULL || *location_p == _DBUS_DUMMY_CONDVAR); +- +- _dbus_list_remove (&uninitialized_condvar_list, location_p); +- } ++ if (*location_p != NULL) ++ _dbus_platform_condvar_free (*location_p); + } + + /** +@@ -304,8 +240,10 @@ void + _dbus_condvar_wait (DBusCondVar *cond, + DBusCMutex *mutex) + { +- if (cond && mutex && thread_init_generation == _dbus_current_generation) +- _dbus_platform_condvar_wait (cond, mutex); ++ if (cond == NULL || mutex == NULL) ++ return; ++ ++ _dbus_platform_condvar_wait (cond, mutex); + } + + /** +@@ -324,11 +262,11 @@ _dbus_condvar_wait_timeout (DBusCondVar *cond, + DBusCMutex *mutex, + int timeout_milliseconds) + { +- if (cond && mutex && thread_init_generation == _dbus_current_generation) +- return _dbus_platform_condvar_wait_timeout (cond, mutex, +- timeout_milliseconds); +- else ++ if (cond == NULL || mutex == NULL) + return TRUE; ++ ++ return _dbus_platform_condvar_wait_timeout (cond, mutex, ++ timeout_milliseconds); + } + + /** +@@ -339,8 +277,10 @@ _dbus_condvar_wait_timeout (DBusCondVar *cond, + void + _dbus_condvar_wake_one (DBusCondVar *cond) + { +- if (cond && thread_init_generation == _dbus_current_generation) +- _dbus_platform_condvar_wake_one (cond); ++ if (cond == NULL) ++ return; ++ ++ _dbus_platform_condvar_wake_one (cond); + } + + static DBusRMutex *global_locks[_DBUS_N_GLOBAL_LOCKS] = { NULL }; +@@ -358,132 +298,6 @@ shutdown_global_locks (void *nil) + } + } + +-static void +-shutdown_uninitialized_locks (void *data) +-{ +- _dbus_list_clear (&uninitialized_rmutex_list); +- _dbus_list_clear (&uninitialized_cmutex_list); +- _dbus_list_clear (&uninitialized_condvar_list); +-} +- +-/* init_global_locks() must be called first. */ +-static dbus_bool_t +-init_uninitialized_locks (void) +-{ +- DBusList *link; +- dbus_bool_t ok; +- +- _dbus_assert (thread_init_generation != _dbus_current_generation); +- +- link = uninitialized_rmutex_list; +- while (link != NULL) +- { +- DBusRMutex **mp; +- +- mp = link->data; +- _dbus_assert (*mp == _DBUS_DUMMY_RMUTEX); +- +- *mp = _dbus_platform_rmutex_new (); +- if (*mp == NULL) +- goto fail_mutex; +- +- link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link); +- } +- +- link = uninitialized_cmutex_list; +- while (link != NULL) +- { +- DBusCMutex **mp; +- +- mp = link->data; +- _dbus_assert (*mp == _DBUS_DUMMY_CMUTEX); +- +- *mp = _dbus_platform_cmutex_new (); +- if (*mp == NULL) +- goto fail_mutex; +- +- link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link); +- } +- +- link = uninitialized_condvar_list; +- while (link != NULL) +- { +- DBusCondVar **cp; +- +- cp = (DBusCondVar **)link->data; +- _dbus_assert (*cp == _DBUS_DUMMY_CONDVAR); +- +- *cp = _dbus_platform_condvar_new (); +- if (*cp == NULL) +- goto fail_condvar; +- +- link = _dbus_list_get_next_link (&uninitialized_condvar_list, link); +- } +- +- _dbus_list_clear (&uninitialized_rmutex_list); +- _dbus_list_clear (&uninitialized_cmutex_list); +- _dbus_list_clear (&uninitialized_condvar_list); +- +- /* This assumes that init_global_locks() has already been called. */ +- _dbus_platform_rmutex_lock (global_locks[_DBUS_LOCK_shutdown_funcs]); +- ok = _dbus_register_shutdown_func_unlocked (shutdown_uninitialized_locks, NULL); +- _dbus_platform_rmutex_unlock (global_locks[_DBUS_LOCK_shutdown_funcs]); +- +- if (!ok) +- goto fail_condvar; +- +- return TRUE; +- +- fail_condvar: +- link = uninitialized_condvar_list; +- while (link != NULL) +- { +- DBusCondVar **cp; +- +- cp = link->data; +- +- if (*cp != _DBUS_DUMMY_CONDVAR && *cp != NULL) +- _dbus_platform_condvar_free (*cp); +- +- *cp = _DBUS_DUMMY_CONDVAR; +- +- link = _dbus_list_get_next_link (&uninitialized_condvar_list, link); +- } +- +- fail_mutex: +- link = uninitialized_rmutex_list; +- while (link != NULL) +- { +- DBusRMutex **mp; +- +- mp = link->data; +- +- if (*mp != _DBUS_DUMMY_RMUTEX && *mp != NULL) +- _dbus_platform_rmutex_free (*mp); +- +- *mp = _DBUS_DUMMY_RMUTEX; +- +- link = _dbus_list_get_next_link (&uninitialized_rmutex_list, link); +- } +- +- link = uninitialized_cmutex_list; +- while (link != NULL) +- { +- DBusCMutex **mp; +- +- mp = link->data; +- +- if (*mp != _DBUS_DUMMY_CMUTEX && *mp != NULL) +- _dbus_platform_cmutex_free (*mp); +- +- *mp = _DBUS_DUMMY_CMUTEX; +- +- link = _dbus_list_get_next_link (&uninitialized_cmutex_list, link); +- } +- +- return FALSE; +-} +- + static dbus_bool_t + init_global_locks (void) + { +@@ -585,9 +399,7 @@ dbus_threads_init (const DBusThreadFunctions *functions) + } + + if (!_dbus_threads_init_platform_specific() || +- /* init_global_locks() must be called before init_uninitialized_locks. */ +- !init_global_locks () || +- !init_uninitialized_locks ()) ++ !init_global_locks ()) + { + _dbus_threads_unlock_platform_specific (); + return FALSE; diff --git a/recipes-core/dbus/files/0011-Add-a-statically-initialized-implementation-of-_dbus.patch b/recipes-core/dbus/files/0011-Add-a-statically-initialized-implementation-of-_dbus.patch new file mode 100644 index 0000000..5f380a9 --- /dev/null +++ b/recipes-core/dbus/files/0011-Add-a-statically-initialized-implementation-of-_dbus.patch @@ -0,0 +1,122 @@ +From: Simon McVittie +Date: Tue, 16 Apr 2013 16:48:11 +0100 +Subject: Add a statically-initialized implementation of _dbus_lock() on glibc + systems + +Bug: https://bugs.freedesktop.org/show_bug.cgi?id=54972 +Signed-off-by: Simon McVittie +Reviewed-by: Alban Crequy +Reviewed-by: Anas Nashif +Bug-Tizen: TZPC-1971 +Applied-upstream: 1.7.6, commit:83aaa9f359e90d3b8cae5d17f6d9ba4600cff68b +Change-Id: Iee8ec5e2138ad8398efbe1cd16b46e61cee08670 +--- + dbus/dbus-sysdeps-pthread.c | 47 ++++++++++++++++++++++++++++++++++++++++++++ + dbus/dbus-threads-internal.h | 6 ++++++ + dbus/dbus-threads.c | 14 +++++++++++++ + 3 files changed, 67 insertions(+) + +diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c +index 1b5d0ba..da7d937 100644 +--- a/dbus/dbus-sysdeps-pthread.c ++++ b/dbus/dbus-sysdeps-pthread.c +@@ -298,3 +298,50 @@ _dbus_threads_unlock_platform_specific (void) + { + pthread_mutex_unlock (&init_mutex); + } ++ ++#ifdef DBUS_HAVE_STATIC_RECURSIVE_MUTEXES ++ ++static pthread_mutex_t global_locks[] = { ++ /* 0-4 */ ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ /* 5-9 */ ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ /* 10-11 */ ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP, ++ PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP ++}; ++ ++_DBUS_STATIC_ASSERT (_DBUS_N_ELEMENTS (global_locks) == _DBUS_N_GLOBAL_LOCKS); ++ ++dbus_bool_t ++_dbus_lock (DBusGlobalLock lock) ++{ ++ /* No initialization is needed. */ ++ _dbus_assert (lock >= 0); ++ _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); ++ ++ PTHREAD_CHECK ("pthread_mutex_lock", ++ pthread_mutex_lock (&(global_locks[lock]))); ++ return TRUE; ++} ++ ++void ++_dbus_unlock (DBusGlobalLock lock) ++{ ++ /* No initialization is needed. */ ++ _dbus_assert (lock >= 0); ++ _dbus_assert (lock < _DBUS_N_GLOBAL_LOCKS); ++ ++ PTHREAD_CHECK ("pthread_mutex_unlock", ++ pthread_mutex_unlock (&(global_locks[lock]))); ++} ++ ++#endif +diff --git a/dbus/dbus-threads-internal.h b/dbus/dbus-threads-internal.h +index 64e8bac..228a8c0 100644 +--- a/dbus/dbus-threads-internal.h ++++ b/dbus/dbus-threads-internal.h +@@ -32,6 +32,12 @@ + * @{ + */ + ++/* glibc can implement global locks without needing an initialization step, ++ * which improves our thread-safety-by-default further. */ ++#if defined(__GLIBC__) && defined(PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP) ++# define DBUS_HAVE_STATIC_RECURSIVE_MUTEXES 1 ++#endif ++ + /** + * A mutex which is recursive if possible, else non-recursive. + * This is typically recursive, but that cannot be relied upon. +diff --git a/dbus/dbus-threads.c b/dbus/dbus-threads.c +index 29462eb..1781bda 100644 +--- a/dbus/dbus-threads.c ++++ b/dbus/dbus-threads.c +@@ -283,6 +283,18 @@ _dbus_condvar_wake_one (DBusCondVar *cond) + _dbus_platform_condvar_wake_one (cond); + } + ++#ifdef DBUS_HAVE_STATIC_RECURSIVE_MUTEXES ++ ++static dbus_bool_t ++init_global_locks (void) ++{ ++ return TRUE; ++} ++ ++/* implementations in dbus-sysdeps-pthread.c */ ++ ++#else /* !defined(DBUS_HAVE_STATIC_RECURSIVE_MUTEXES) */ ++ + static DBusRMutex *global_locks[_DBUS_N_GLOBAL_LOCKS] = { NULL }; + + static void +@@ -356,6 +368,8 @@ _dbus_unlock (DBusGlobalLock lock) + _dbus_platform_rmutex_unlock (global_locks[lock]); + } + ++#endif /* !defined(DBUS_HAVE_STATIC_RECURSIVE_MUTEXES) */ ++ + /** @} */ /* end of internals */ + + /** diff --git a/recipes-core/dbus/files/0012-Enable-checking-of-smack-context-from-DBus-interface.patch b/recipes-core/dbus/files/0012-Enable-checking-of-smack-context-from-DBus-interface.patch new file mode 100644 index 0000000..5393bb9 --- /dev/null +++ b/recipes-core/dbus/files/0012-Enable-checking-of-smack-context-from-DBus-interface.patch @@ -0,0 +1,341 @@ +From: Brian McGillion +Date: Mon, 6 Feb 2012 18:46:05 +0200 +Subject: Enable checking of smack context from DBus interface + +--- + bus/Makefile.am | 4 ++ + bus/driver.c | 6 +++ + bus/smack.c | 132 +++++++++++++++++++++++++++++++++++++++++++++++ + bus/smack.h | 36 +++++++++++++ + cmake/CMakeLists.txt | 3 ++ + cmake/bus/CMakeLists.txt | 4 +- + configure.ac | 17 +++++- + 7 files changed, 199 insertions(+), 3 deletions(-) + create mode 100644 bus/smack.c + create mode 100644 bus/smack.h + +diff --git a/bus/Makefile.am b/bus/Makefile.am +index 6cbc09a..7f63d86 100644 +--- a/bus/Makefile.am ++++ b/bus/Makefile.am +@@ -7,6 +7,7 @@ DBUS_BUS_LIBS = \ + $(THREAD_LIBS) \ + $(ADT_LIBS) \ + $(NETWORK_libs) \ ++ $(LIBSMACK_LIBS) \ + $(NULL) + + DBUS_LAUNCHER_LIBS = \ +@@ -21,6 +22,7 @@ AM_CPPFLAGS = \ + -DDBUS_SYSTEM_CONFIG_FILE=\""$(configdir)/system.conf"\" \ + -DDBUS_COMPILATION \ + -DDBUS_STATIC_BUILD \ ++ $(LIBSMACK_CFLAGS) \ + $(NULL) + + # if assertions are enabled, improve backtraces +@@ -93,6 +95,8 @@ BUS_SOURCES= \ + services.h \ + signals.c \ + signals.h \ ++ smack.c \ ++ smack.h \ + stats.c \ + stats.h \ + test.c \ +diff --git a/bus/driver.c b/bus/driver.c +index 574e0f3..c6298d7 100644 +--- a/bus/driver.c ++++ b/bus/driver.c +@@ -30,6 +30,7 @@ + #include "services.h" + #include "selinux.h" + #include "signals.h" ++#include "smack.h" + #include "stats.h" + #include "utils.h" + #include +@@ -38,6 +39,7 @@ + #include + #include + ++ + static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection, + DBusMessage *hello_message, + BusTransaction *transaction, +@@ -1736,6 +1738,10 @@ static const MessageHandler dbus_message_handlers[] = { + "", + DBUS_TYPE_STRING_AS_STRING, + bus_driver_handle_get_id }, ++ { "GetConnectionSmackContext", ++ DBUS_TYPE_STRING_AS_STRING, ++ DBUS_TYPE_STRING_AS_STRING, ++ bus_smack_handle_get_connection_context }, + { NULL, NULL, NULL, NULL } + }; + +diff --git a/bus/smack.c b/bus/smack.c +new file mode 100644 +index 0000000..b8542c2 +--- /dev/null ++++ b/bus/smack.c +@@ -0,0 +1,132 @@ ++/* smack.c - Provide interface to query smack context ++ * ++ * Author: Brian McGillion ++ * Copyright © 2011 Intel Corporation ++ * ++ * Licensed under the Academic Free License version 2.1 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ */ ++ ++#include ++#include "smack.h" ++ ++#include ++ ++#include "connection.h" ++#include "services.h" ++#include "utils.h" ++ ++#ifdef DBUS_ENABLE_SMACK ++#include ++#endif ++ ++#ifdef DBUS_ENABLE_SMACK ++static char * ++bus_smack_get_label (DBusConnection *connection) ++{ ++ char *label; ++ int sock_fd; ++ ++ if (!dbus_connection_get_socket(connection, &sock_fd)) ++ return NULL; ++ ++ if (smack_new_label_from_socket(sock_fd, &label) < 0) ++ return NULL; ++ return label; ++} ++#endif ++ ++dbus_bool_t ++bus_smack_handle_get_connection_context (DBusConnection *connection, ++ BusTransaction *transaction, ++ DBusMessage *message, ++ DBusError *error) ++{ ++#ifdef DBUS_ENABLE_SMACK ++ const char *remote_end = NULL; ++ BusRegistry *registry; ++ DBusString remote_end_str; ++ BusService *service; ++ DBusConnection *remote_connection; ++ DBusMessage *reply = NULL; ++ char *label; ++ ++ _DBUS_ASSERT_ERROR_IS_CLEAR (error); ++ ++ registry = bus_connection_get_registry (connection); ++ ++ if (!dbus_message_get_args (message, error, DBUS_TYPE_STRING, &remote_end, ++ DBUS_TYPE_INVALID)) ++ return FALSE; ++ ++ _dbus_verbose ("asked for label of connection %s\n", remote_end); ++ ++ _dbus_string_init_const (&remote_end_str, remote_end); ++ ++ service = bus_registry_lookup (registry, &remote_end_str); ++ if (service == NULL) ++ { ++ dbus_set_error (error, DBUS_ERROR_NAME_HAS_NO_OWNER, ++ "Bus name '%s' has no owner", remote_end); ++ return FALSE; ++ } ++ ++ remote_connection = bus_service_get_primary_owners_connection (service); ++ if (remote_connection == NULL) ++ goto oom; ++ ++ reply = dbus_message_new_method_return (message); ++ if (reply == NULL) ++ goto oom; ++ ++ label = bus_smack_get_label (remote_connection); ++ if (label == NULL) ++ { ++ dbus_set_error (error, DBUS_ERROR_FAILED, ++ "Failed to get the socket fd of the connection", ++ remote_end); ++ goto err; ++ } ++ ++ if (!dbus_message_append_args (reply, DBUS_TYPE_STRING, ++ &label, DBUS_TYPE_INVALID)) ++ goto oom; ++ ++ if (!bus_transaction_send_from_driver (transaction, connection, reply)) ++ goto oom; ++ ++ dbus_message_unref (reply); ++ dbus_free(label); ++ ++ return TRUE; ++ ++oom: ++ BUS_SET_OOM (error); ++ ++err: ++ if (reply != NULL) ++ dbus_message_unref (reply); ++ ++ dbus_free(label); ++ ++ return FALSE; ++#else ++ dbus_set_error (error, DBUS_ERROR_NOT_SUPPORTED, ++ "SMACK support is not enabled"); ++ return FALSE; ++#endif ++} +diff --git a/bus/smack.h b/bus/smack.h +new file mode 100644 +index 0000000..04a4a2a +--- /dev/null ++++ b/bus/smack.h +@@ -0,0 +1,36 @@ ++/* smack.h - Provide interface to query smack context ++ * ++ * Author: Brian McGillion ++ * Copyright © 2011 Intel Corporation ++ * ++ * Based on example from Stats interface ++ * ++ * Licensed under the Academic Free License version 2.1 ++ * ++ * This program is free software; you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation; either version 2 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program; if not, write to the Free Software ++ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA ++ * 02110-1301 USA ++ */ ++ ++#ifndef SMACK_H ++#define SMACK_H ++ ++#include "bus.h" ++ ++dbus_bool_t bus_smack_handle_get_connection_context (DBusConnection *connection, ++ BusTransaction *transaction, ++ DBusMessage *message, ++ DBusError *error); ++ ++#endif // SMACK_H +diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt +index 000acda..68b7a9e 100644 +--- a/cmake/CMakeLists.txt ++++ b/cmake/CMakeLists.txt +@@ -94,6 +94,8 @@ option (DBUS_ENABLE_STATS "enable bus daemon usage statistics" OFF) + + option (DBUS_ENABLE_STATS "enable bus daemon usage statistics" OFF) + ++option (DBUS_ENABLE_SMACK "enable smack checks in the daemon" OFF) ++ + if (DBUS_USE_EXPAT) + find_package(LibExpat) + else () +@@ -555,6 +557,7 @@ message(" Building bus stats API: ${DBUS_ENABLE_STATS} " + message(" installing system libs: ${DBUS_INSTALL_SYSTEM_LIBS} ") + #message(" Building SELinux support: ${have_selinux} ") + #message(" Building dnotify support: ${have_dnotify} ") ++message(" Building Smack support: ${DBUS_ENABLE_SMACK} ") + message(" Building Doxygen docs: ${DBUS_ENABLE_DOXYGEN_DOCS} ") + message(" Building XML docs: ${DBUS_ENABLE_XML_DOCS} ") + #message(" Gettext libs (empty OK): ${INTLLIBS} ") +diff --git a/cmake/bus/CMakeLists.txt b/cmake/bus/CMakeLists.txt +index 2657605..13fb34c 100644 +--- a/cmake/bus/CMakeLists.txt ++++ b/cmake/bus/CMakeLists.txt +@@ -72,7 +72,9 @@ set (BUS_SOURCES + ${BUS_DIR}/test.c + ${BUS_DIR}/test.h + ${BUS_DIR}/utils.c +- ${BUS_DIR}/utils.h ++ ${BUS_DIR}/utils.h ++ ${BUS_DIR}/smack.c ++ ${BUS_DIR}/smack.h + ${XML_SOURCES} + ${DIR_WATCH_SOURCE} + ) +diff --git a/configure.ac b/configure.ac +index a963d4d..95216c5 100644 +--- a/configure.ac ++++ b/configure.ac +@@ -207,6 +207,9 @@ if test "x$enable_embedded_tests" = xyes; then + [Define to build test code into the library and binaries]) + fi + ++# call early to ensure availability ++PKG_PROG_PKG_CONFIG ++ + # DBUS_ENABLE_MODULAR_TESTS controls tests that work based on public API. + # These use GTest, from GLib, because life's too short. They're enabled by + # default (unless you don't have GLib), because they don't bloat the library +@@ -907,8 +910,6 @@ fi + # unix:path=/foo or unix:abstract=/foo + AC_SUBST(DBUS_PATH_OR_ABSTRACT) + +-PKG_PROG_PKG_CONFIG +- + #### Sort out XML library + + # see what we have +@@ -1703,6 +1704,17 @@ if test "x$enable_stats" = xyes; then + [Define to enable bus daemon usage statistics]) + fi + ++#enable smack label support ++AC_ARG_ENABLE([smack], [AS_HELP_STRING([--enable-smack], [enable SMACK security checks])], [], [enable_smack=no]) ++if test "x$enable_smack" = xyes; then ++ PKG_CHECK_MODULES([LIBSMACK], [libsmack >= 1.0], ++ [AC_DEFINE([DBUS_ENABLE_SMACK], [1], [Define to enable SMACK security features])], ++ [AC_MSG_ERROR([libsmack is required to enable smack support])]) ++fi ++ ++AC_SUBST([LIBSMACK_CFLAGS]) ++AC_SUBST([LIBSMACK_LIBS]) ++ + AC_CONFIG_FILES([ + Doxyfile + dbus/versioninfo.rc +@@ -1781,6 +1793,7 @@ echo " + Building checks: ${enable_checks} + Building bus stats API: ${enable_stats} + Building SELinux support: ${have_selinux} ++ Building SMACK support: ${enable_smack} + Building inotify support: ${have_inotify} + Building dnotify support: ${have_dnotify} + Building kqueue support: ${have_kqueue} diff --git a/recipes-core/dbus/files/0013-Enforce-smack-policy-from-conf-file.patch b/recipes-core/dbus/files/0013-Enforce-smack-policy-from-conf-file.patch new file mode 100644 index 0000000..c54f5af --- /dev/null +++ b/recipes-core/dbus/files/0013-Enforce-smack-policy-from-conf-file.patch @@ -0,0 +1,481 @@ +From: Brian McGillion +Date: Mon, 6 Feb 2012 18:48:30 +0200 +Subject: Enforce smack policy from conf file + +--- + bus/config-parser.c | 38 ++++++++++---- + bus/policy.c | 141 +++++++++++++++++++++++++++++++++++++++++++++++++--- + bus/policy.h | 3 ++ + bus/smack.c | 111 +++++++++++++++++++++++++++++++++++++++++ + bus/smack.h | 4 ++ + 5 files changed, 278 insertions(+), 19 deletions(-) + +diff --git a/bus/config-parser.c b/bus/config-parser.c +index 07e8fbb..d7ba549 100644 +--- a/bus/config-parser.c ++++ b/bus/config-parser.c +@@ -43,6 +43,7 @@ typedef enum + POLICY_MANDATORY, + POLICY_USER, + POLICY_GROUP, ++ POLICY_SMACK, + POLICY_CONSOLE + } PolicyType; + +@@ -64,7 +65,11 @@ typedef struct + struct + { + PolicyType type; +- unsigned long gid_uid_or_at_console; ++ union ++ { ++ unsigned long gid_uid_or_at_console; ++ char *smack_label; ++ }; + } policy; + + struct +@@ -150,6 +155,8 @@ element_free (Element *e) + { + if (e->type == ELEMENT_LIMIT) + dbus_free (e->d.limit.name); ++ else if (e->type == ELEMENT_POLICY && e->d.policy.type == POLICY_SMACK) ++ dbus_free (e->d.policy.smack_label); + + dbus_free (e); + } +@@ -972,6 +979,7 @@ start_busconfig_child (BusConfigParser *parser, + const char *user; + const char *group; + const char *at_console; ++ const char *smack; + + if ((e = push_element (parser, ELEMENT_POLICY)) == NULL) + { +@@ -988,20 +996,16 @@ start_busconfig_child (BusConfigParser *parser, + "context", &context, + "user", &user, + "group", &group, ++ "smack", &smack, + "at_console", &at_console, + NULL)) + return FALSE; + +- if (((context && user) || +- (context && group) || +- (context && at_console)) || +- ((user && group) || +- (user && at_console)) || +- (group && at_console) || +- !(context || user || group || at_console)) ++ if (((context != NULL) + (user != NULL) + (group != NULL) + ++ (smack != NULL) + (at_console != NULL)) != 1) + { + dbus_set_error (error, DBUS_ERROR_FAILED, +- " element must have exactly one of (context|user|group|at_console) attributes"); ++ " element must have exactly one of (context|user|group|smack|at_console) attributes"); + return FALSE; + } + +@@ -1047,6 +1051,16 @@ start_busconfig_child (BusConfigParser *parser, + _dbus_warn ("Unknown group \"%s\" in message bus configuration file\n", + group); + } ++ else if (smack != NULL) ++ { ++ e->d.policy.type = POLICY_SMACK; ++ e->d.policy.smack_label = _dbus_strdup (smack); ++ if (e->d.policy.smack_label == NULL) ++ { ++ BUS_SET_OOM (error); ++ return FALSE; ++ } ++ } + else if (at_console != NULL) + { + dbus_bool_t t; +@@ -1631,8 +1645,10 @@ append_rule_from_element (BusConfigParser *parser, + rule)) + goto nomem; + break; +- +- ++ case POLICY_SMACK: ++ if (!bus_policy_append_smack_rule (parser->policy, pe->d.policy.smack_label, rule)) ++ goto nomem; ++ break; + case POLICY_CONSOLE: + if (!bus_policy_append_console_rule (parser->policy, pe->d.policy.gid_uid_or_at_console, + rule)) +diff --git a/bus/policy.c b/bus/policy.c +index 379cea9..836354a 100644 +--- a/bus/policy.c ++++ b/bus/policy.c +@@ -26,6 +26,7 @@ + #include "services.h" + #include "test.h" + #include "utils.h" ++#include "smack.h" + #include + #include + #include +@@ -126,12 +127,13 @@ struct BusPolicy + { + int refcount; + +- DBusList *default_rules; /**< Default policy rules */ +- DBusList *mandatory_rules; /**< Mandatory policy rules */ +- DBusHashTable *rules_by_uid; /**< per-UID policy rules */ +- DBusHashTable *rules_by_gid; /**< per-GID policy rules */ +- DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/ +- DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/ ++ DBusList *default_rules; /**< Default policy rules */ ++ DBusList *mandatory_rules; /**< Mandatory policy rules */ ++ DBusHashTable *rules_by_uid; /**< per-UID policy rules */ ++ DBusHashTable *rules_by_gid; /**< per-GID policy rules */ ++ DBusHashTable *rules_by_smack_label; /**< per-SMACK label policy rules */ ++ DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/ ++ DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/ + }; + + static void +@@ -181,6 +183,14 @@ bus_policy_new (void) + if (policy->rules_by_gid == NULL) + goto failed; + ++#ifdef DBUS_ENABLE_SMACK ++ policy->rules_by_smack_label = _dbus_hash_table_new (DBUS_HASH_STRING, ++ (DBusFreeFunction) dbus_free, ++ free_rule_list_func); ++ if (policy->rules_by_smack_label == NULL) ++ goto failed; ++#endif ++ + return policy; + + failed: +@@ -230,7 +240,13 @@ bus_policy_unref (BusPolicy *policy) + _dbus_hash_table_unref (policy->rules_by_gid); + policy->rules_by_gid = NULL; + } +- ++ ++ if (policy->rules_by_smack_label) ++ { ++ _dbus_hash_table_unref (policy->rules_by_smack_label); ++ policy->rules_by_smack_label = NULL; ++ } ++ + dbus_free (policy); + } + } +@@ -356,6 +372,24 @@ bus_policy_create_client_policy (BusPolicy *policy, + } + } + ++ if (policy->rules_by_smack_label && ++ _dbus_hash_table_get_n_entries (policy->rules_by_smack_label) > 0) ++ { ++ DBusList **list; ++ dbus_bool_t nomem_err = FALSE; ++ ++ list = bus_smack_generate_allowed_list(connection, policy->rules_by_smack_label, &nomem_err); ++ ++ if (list != NULL) ++ { ++ nomem_err = !add_list_to_client (list, client); ++ _dbus_list_clear (list); ++ } ++ ++ if (nomem_err) ++ goto nomem; ++ } ++ + if (!add_list_to_client (&policy->mandatory_rules, + client)) + goto nomem; +@@ -576,6 +610,66 @@ bus_policy_append_group_rule (BusPolicy *policy, + return TRUE; + } + ++#ifdef DBUS_ENABLE_SMACK ++static DBusList ** ++get_list_string (DBusHashTable *table, ++ const char *key) ++{ ++ DBusList **list; ++ ++ if (key == NULL) ++ return NULL; ++ ++ list = _dbus_hash_table_lookup_string (table, key); ++ ++ if (list == NULL) ++ { ++ char *new_key; ++ ++ list = dbus_new0 (DBusList*, 1); ++ if (list == NULL) ++ return NULL; ++ ++ new_key = _dbus_strdup (key); ++ if (new_key == NULL) ++ { ++ dbus_free (list); ++ return NULL; ++ } ++ ++ if (!_dbus_hash_table_insert_string (table, new_key, list)) ++ { ++ dbus_free (list); ++ dbus_free (new_key); ++ return NULL; ++ } ++ } ++ ++ return list; ++} ++#endif ++ ++dbus_bool_t ++bus_policy_append_smack_rule (BusPolicy *policy, ++ const char *label, ++ BusPolicyRule *rule) ++{ ++#ifdef DBUS_ENABLE_SMACK ++ DBusList **list; ++ ++ list = get_list_string (policy->rules_by_smack_label, label); ++ if (list == NULL) ++ return FALSE; ++ ++ if (!_dbus_list_append (list, rule)) ++ return FALSE; ++ ++ bus_policy_rule_ref (rule); ++#endif ++ ++ return TRUE; ++} ++ + dbus_bool_t + bus_policy_append_console_rule (BusPolicy *policy, + dbus_bool_t at_console, +@@ -653,6 +747,31 @@ merge_id_hash (DBusHashTable *dest, + return TRUE; + } + ++#ifdef DBUS_ENABLE_SMACK ++static dbus_bool_t ++merge_string_hash (DBusHashTable *dest, ++ DBusHashTable *to_absorb) ++{ ++ DBusHashIter iter; ++ ++ _dbus_hash_iter_init (to_absorb, &iter); ++ while (_dbus_hash_iter_next (&iter)) ++ { ++ const char *absorb_label = _dbus_hash_iter_get_string_key(&iter); ++ DBusList **list = _dbus_hash_iter_get_value (&iter); ++ DBusList **target = get_list_string (dest, absorb_label); ++ ++ if (target == NULL) ++ return FALSE; ++ ++ if (!append_copy_of_policy_list (target, list)) ++ return FALSE; ++ } ++ ++ return TRUE; ++} ++#endif ++ + dbus_bool_t + bus_policy_merge (BusPolicy *policy, + BusPolicy *to_absorb) +@@ -685,6 +804,12 @@ bus_policy_merge (BusPolicy *policy, + to_absorb->rules_by_gid)) + return FALSE; + ++#ifdef DBUS_ENABLE_SMACK ++ if (!merge_string_hash (policy->rules_by_smack_label, ++ to_absorb->rules_by_smack_label)) ++ return FALSE; ++#endif ++ + return TRUE; + } + +@@ -873,7 +998,7 @@ bus_client_policy_check_can_send (BusClientPolicy *policy, + { + DBusList *link; + dbus_bool_t allowed; +- ++ + /* policy->rules is in the order the rules appeared + * in the config file, i.e. last rule that applies wins + */ +diff --git a/bus/policy.h b/bus/policy.h +index 3ff6f48..20d0a39 100644 +--- a/bus/policy.h ++++ b/bus/policy.h +@@ -130,6 +130,9 @@ dbus_bool_t bus_policy_append_user_rule (BusPolicy *policy, + dbus_bool_t bus_policy_append_group_rule (BusPolicy *policy, + dbus_gid_t gid, + BusPolicyRule *rule); ++dbus_bool_t bus_policy_append_smack_rule (BusPolicy *policy, ++ const char *label, ++ BusPolicyRule *rule); + dbus_bool_t bus_policy_append_console_rule (BusPolicy *policy, + dbus_bool_t at_console, + BusPolicyRule *rule); +diff --git a/bus/smack.c b/bus/smack.c +index b8542c2..d4546a3 100644 +--- a/bus/smack.c ++++ b/bus/smack.c +@@ -29,11 +29,17 @@ + #include "connection.h" + #include "services.h" + #include "utils.h" ++#include "policy.h" + + #ifdef DBUS_ENABLE_SMACK + #include + #endif + ++#define SMACK_WRITE "W" ++#define SMACK_READ "R" ++#define SMACK_READ_WRITE "RW" ++ ++ + #ifdef DBUS_ENABLE_SMACK + static char * + bus_smack_get_label (DBusConnection *connection) +@@ -130,3 +136,108 @@ err: + return FALSE; + #endif + } ++ ++#ifdef DBUS_ENABLE_SMACK ++static dbus_bool_t ++bus_smack_has_access (const char *subject, const char *object, ++ const char *access) ++{ ++ return (smack_have_access (subject, object, access) == 1 ? TRUE : FALSE); ++} ++#endif ++ ++ ++/** ++ * Calculate the list of rules that apply to a connection. ++ * ++ * @param connection The inbound conenction ++ * @param rules_by_smack_label The table of object labels -> rules mapping ++ * @param nomem_err (out) If a nomem situation is encountered this value is set to TRUE. ++ * @returns the list of permitted rules if it exists and no errors were encountered otherwise NULL. ++ */ ++DBusList** ++bus_smack_generate_allowed_list (DBusConnection *connection, ++ DBusHashTable *rules_by_smack_label, ++ dbus_bool_t *nomem_err) ++{ ++#ifdef DBUS_ENABLE_SMACK ++ char *subject_label; ++ DBusHashIter iter; ++ dbus_bool_t is_allowed; ++ DBusList **allowed_list; ++ ++ /* the label of the subject, is the label on the new connection, ++ either the service itself or one of its clients */ ++ subject_label = bus_smack_get_label (connection); ++ if (subject_label == NULL) ++ return NULL; ++ ++ allowed_list = dbus_new0 (DBusList*, 1); ++ if (allowed_list == NULL) ++ goto nomem; ++ ++ /* Iterate over all the smack labels we have parsed from the .conf files */ ++ _dbus_hash_iter_init (rules_by_smack_label, &iter); ++ while (_dbus_hash_iter_next (&iter)) ++ { ++ DBusList *link; ++ const char *object_label = _dbus_hash_iter_get_string_key (&iter); ++ /* the list here is all the rules that are 'protected' ++ by the SMACK label named $object_label */ ++ DBusList **list = _dbus_hash_iter_get_value (&iter); ++ ++ link = _dbus_list_get_first_link (list); ++ while (link != NULL) ++ { ++ BusPolicyRule *rule = link->data; ++ link = _dbus_list_get_next_link (list, link); ++ is_allowed = FALSE; ++ ++ switch (rule->type) ++ { ++ case BUS_POLICY_RULE_OWN: ++ is_allowed = bus_smack_has_access (subject_label, ++ object_label, ++ SMACK_READ_WRITE); ++ break; ++ case BUS_POLICY_RULE_SEND: ++ is_allowed = bus_smack_has_access (subject_label, ++ object_label, ++ SMACK_WRITE); ++ break; ++ case BUS_POLICY_RULE_RECEIVE: ++ is_allowed = bus_smack_has_access (subject_label, ++ object_label, ++ SMACK_READ); ++ break; ++ default: ++ continue; ++ } ++ ++ if (is_allowed) ++ { ++ if (!_dbus_list_append (allowed_list, rule)) ++ goto nomem; ++ ++ bus_policy_rule_ref (rule); ++ } ++ ++ _dbus_verbose ("permission request subject (%s) -> object (%s) : %s", subject_label, object_label, (is_allowed ? "GRANTED" : "REJECTED")); ++ } ++ } ++ ++ dbus_free(subject_label); ++ return allowed_list; ++ ++nomem: ++ if (allowed_list != NULL) ++ _dbus_list_clear (allowed_list); ++ ++ dbus_free(subject_label); ++ *nomem_err = TRUE; ++ return NULL; ++ ++#else ++ return NULL; ++#endif ++} +diff --git a/bus/smack.h b/bus/smack.h +index 04a4a2a..6b1dfad 100644 +--- a/bus/smack.h ++++ b/bus/smack.h +@@ -27,10 +27,14 @@ + #define SMACK_H + + #include "bus.h" ++#include + + dbus_bool_t bus_smack_handle_get_connection_context (DBusConnection *connection, + BusTransaction *transaction, + DBusMessage *message, + DBusError *error); + ++DBusList **bus_smack_generate_allowed_list (DBusConnection *connection, ++ DBusHashTable *label_rules, ++ dbus_bool_t *error); + #endif // SMACK_H -- 2.7.4