Bug#689602: pu: package dbus/1.2.24-4+squeeze2
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
Usertags: pu
CVE-2012-3524 (#689070) is a local root privilege escalation vulnerability
when setuid-root applications use libdbus without first sanitizing their
caller-supplied environment via a whitelist. Applications thought to be
exploitable include Xorg via the setuid /usr/bin/X if using libhal (so for us,
kFreeBSD but not Linux), and perhaps su/sudo if libpam-systemd or
libpam-ck-connector is used. I wasn't able to exploit libpam-ck-connector
under a squeeze VM, but perhaps I'm doing it wrong.
D-Bus upstream consensus is that it is an application bug to use any
non-trivial library in a setuid application without first clearing the
caller-supplied environment; but having said that, hardening libdbus
against applications with this bug seems wise.
When I asked for security team feedback on #689070, they requested that I
send this to stable via s-p-u.
This is basically the same as the t-p-u option in #689148, but with the
patches adjusted for the older libdbus in stable.
May I upload? I have source+i386 ready to go; proposed debdiff attached.
Regards,
S
-- System Information:
Debian Release: wheezy/sid
APT prefers testing-proposed-updates
APT policy: (500, 'testing-proposed-updates'), (500, 'unstable'), (500, 'testing'), (500, 'stable'), (1, 'experimental')
Architecture: amd64 (x86_64)
Foreign Architectures: i386
Kernel: Linux 3.2.0-4-amd64 (SMP w/4 CPU cores)
Locale: LANG=en_GB.UTF-8, LC_CTYPE=en_GB.UTF-8 (charmap=UTF-8)
Shell: /bin/sh linked to /bin/dash
diffstat for dbus-1.2.24 dbus-1.2.24
changelog | 12
patches/0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch | 213 ++++++++++
patches/0002-hardening-Ensure-_dbus_check_setuid-is-initialized-t.patch | 36 +
patches/0003-hardening-Remove-activation-helper-handling-for-DBUS.patch | 57 ++
patches/0004-activation-helper-Ensure-DBUS_STARTER_ADDRESS-is-set.patch | 66 +++
patches/series | 4
6 files changed, 388 insertions(+)
diff -Nru dbus-1.2.24/debian/changelog dbus-1.2.24/debian/changelog
--- dbus-1.2.24/debian/changelog 2011-06-14 20:09:38.000000000 +0100
+++ dbus-1.2.24/debian/changelog 2012-10-04 08:47:17.000000000 +0100
@@ -1,3 +1,15 @@
+dbus (1.2.24-4+squeeze2) stable; urgency=low
+
+ * CVE-2012-3524: apply patches from upstream 1.6.6 to avoid arbitrary
+ code execution in setuid/setgid binaries that incorrectly use libdbus
+ without first sanitizing the environment variables inherited from
+ their less-privileged caller (Closes: #689070).
+ - As per upstream 1.6.8, do not check filesystem capabilities for now,
+ only setuid/setgid, fixing regressions in certain configurations of
+ gnome-keyring
+
+ -- Simon McVittie <smcv@debian.org> Thu, 04 Oct 2012 08:47:10 +0100
+
dbus (1.2.24-4+squeeze1) stable; urgency=low
* Update Vcs-* control fields to reflect the move to git
diff -Nru dbus-1.2.24/debian/patches/0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch dbus-1.2.24/debian/patches/0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch
--- dbus-1.2.24/debian/patches/0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch 1970-01-01 01:00:00.000000000 +0100
+++ dbus-1.2.24/debian/patches/0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch 2012-10-04 08:47:17.000000000 +0100
@@ -0,0 +1,213 @@
+From: Colin Walters <walters@verbum.org>
+Date: Wed, 22 Aug 2012 10:03:34 -0400
+Subject: [PATCH 1/5] CVE-2012-3524: Don't access environment variables or run
+ dbus-launch when setuid
+
+This matches a corresponding change in GLib. See
+glib/gutils.c:g_check_setuid().
+
+Some programs attempt to use libdbus when setuid; notably the X.org
+server is shipped in such a configuration. libdbus never had an
+explicit policy about its use in setuid programs.
+
+I'm not sure whether we should advertise such support. However, given
+that there are real-world programs that do this currently, we can make
+them safer with not too much effort.
+
+Better to fix a problem caused by an interaction between two
+components in *both* places if possible.
+
+How to determine whether or not we're running in a privilege-escalated
+path is operating system specific. Note that GTK+'s code to check
+euid versus uid worked historically on Unix, more modern systems have
+filesystem capabilities and SELinux domain transitions, neither of
+which are captured by the uid comparison.
+
+On Linux/glibc, the way this works is that the kernel sets an
+AT_SECURE flag in the ELF auxiliary vector, and glibc looks for it on
+startup. If found, then glibc sets a public-but-undocumented
+__libc_enable_secure variable which we can use. Unfortunately, while
+it *previously* worked to check this variable, a combination of newer
+binutils and RPM break it:
+http://www.openwall.com/lists/owl-dev/2012/08/14/1
+
+So for now on Linux/glibc, we fall back to the historical Unix version
+until we get glibc fixed.
+
+On some BSD variants, there is a issetugid() function. On other Unix
+variants, we fall back to what GTK+ has been doing.
+
+Reported-by: Sebastian Krahmer <krahmer@suse.de>
+Signed-off-by: Colin Walters <walters@verbum.org>
+[backported to 1.2 -smcv]
+Origin: upstream, 1.2.30, commit:083ebe6126a769491c8ef61f8998117440b48861
+[dbus-sysdeps-win changes skipped for Debian: file not in tarball -smcv]
+Bug: https://bugs.freedesktop.org/show_bug.cgi?id=52202
+Bug-CVE: CVE-2012-3524
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=689070
+---
+ configure.in | 2 +-
+ dbus/dbus-keyring.c | 7 ++++++
+ dbus/dbus-sysdeps-unix.c | 62 +++++++++++++++++++++++++++++++++++++++++++++-
+ dbus/dbus-sysdeps-win.c | 6 +++++
+ dbus/dbus-sysdeps.c | 5 ++++
+ dbus/dbus-sysdeps.h | 1 +
+ 6 files changed, 81 insertions(+), 2 deletions(-)
+
+diff --git a/configure.in b/configure.in
+index b027f86..28c11de 100644
+--- a/configure.in
++++ b/configure.in
+@@ -430,7 +430,7 @@ AC_DEFINE_UNQUOTED(DBUS_HAVE_ATOMIC_INT_COND, [$have_atomic_inc_cond],
+ AC_SEARCH_LIBS(socket,[socket network])
+ AC_CHECK_FUNC(gethostbyname,,[AC_CHECK_LIB(nsl,gethostbyname)])
+
+-AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep setenv clearenv unsetenv socketpair getgrouplist fpathconf setrlimit poll)
++AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep setenv clearenv unsetenv socketpair getgrouplist fpathconf setrlimit poll issetugid getresuid)
+
+ #### Check for broken poll; taken from Glib's configure
+
+diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c
+index 6dc1e12..0c32a4f 100644
+--- a/dbus/dbus-keyring.c
++++ b/dbus/dbus-keyring.c
+@@ -718,6 +718,13 @@ _dbus_keyring_new_for_credentials (DBusCredentials *credentials,
+ DBusCredentials *our_credentials;
+
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
++
++ if (_dbus_check_setuid ())
++ {
++ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
++ "Unable to create DBus keyring when setuid");
++ return NULL;
++ }
+
+ keyring = NULL;
+ error_set = FALSE;
+diff --git a/dbus/dbus-sysdeps-unix.c b/dbus/dbus-sysdeps-unix.c
+index b58d09a..d4777c5 100644
+--- a/dbus/dbus-sysdeps-unix.c
++++ b/dbus/dbus-sysdeps-unix.c
+@@ -3124,7 +3124,14 @@ _dbus_get_autolaunch_address (DBusString *address,
+ int i;
+ DBusString uuid;
+ dbus_bool_t retval;
+-
++
++ if (_dbus_check_setuid ())
++ {
++ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
++ "Unable to autolaunch when setuid");
++ return FALSE;
++ }
++
+ _DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ retval = FALSE;
+
+@@ -3510,4 +3517,57 @@ _dbus_get_is_errno_eagain_or_ewouldblock (void)
+ return errno == EAGAIN || errno == EWOULDBLOCK;
+ }
+
++/**
++ * **NOTE**: If you modify this function, please also consider making
++ * the corresponding change in GLib. See
++ * glib/gutils.c:g_check_setuid().
++ *
++ * Returns TRUE if the current process was executed as setuid (or an
++ * equivalent __libc_enable_secure is available). See:
++ * http://osdir.com/ml/linux.lfs.hardened/2007-04/msg00032.html
++ */
++dbus_bool_t
++_dbus_check_setuid (void)
++{
++ /* TODO: get __libc_enable_secure exported from glibc.
++ * See http://www.openwall.com/lists/owl-dev/2012/08/14/1
++ */
++#if 0 && defined(HAVE_LIBC_ENABLE_SECURE)
++ {
++ /* See glibc/include/unistd.h */
++ extern int __libc_enable_secure;
++ return __libc_enable_secure;
++ }
++#elif defined(HAVE_ISSETUGID)
++ /* BSD: http://www.freebsd.org/cgi/man.cgi?query=issetugid&sektion=2 */
++ return issetugid ();
++#else
++ uid_t ruid, euid, suid; /* Real, effective and saved user ID's */
++ gid_t rgid, egid, sgid; /* Real, effective and saved group ID's */
++
++ static dbus_bool_t check_setuid_initialised;
++ static dbus_bool_t is_setuid;
++
++ if (_DBUS_UNLIKELY (!check_setuid_initialised))
++ {
++#ifdef HAVE_GETRESUID
++ if (getresuid (&ruid, &euid, &suid) != 0 ||
++ getresgid (&rgid, &egid, &sgid) != 0)
++#endif /* HAVE_GETRESUID */
++ {
++ suid = ruid = getuid ();
++ sgid = rgid = getgid ();
++ euid = geteuid ();
++ egid = getegid ();
++ }
++
++ check_setuid_initialised = TRUE;
++ is_setuid = (ruid != euid || ruid != suid ||
++ rgid != egid || rgid != sgid);
++
++ }
++ return is_setuid;
++#endif
++}
++
+ /* tests in dbus-sysdeps-util.c */
+#diff --git a/dbus/dbus-sysdeps-win.c b/dbus/dbus-sysdeps-win.c
+#index 02f3123..15fb5cb 100644
+#--- a/dbus/dbus-sysdeps-win.c
+#+++ b/dbus/dbus-sysdeps-win.c
+#@@ -3370,6 +3370,12 @@ _dbus_append_keyring_directory_for_credentials (DBusString *directory,
+# return FALSE;
+# }
+#
+#+dbus_bool_t
+#+_dbus_check_setuid (void)
+#+{
+#+ return FALSE;
+#+}
+#+
+# /** @} end of sysdeps-win */
+# /* tests in dbus-sysdeps-util.c */
+#
+diff --git a/dbus/dbus-sysdeps.c b/dbus/dbus-sysdeps.c
+index ccd80cc..c3acc17 100644
+--- a/dbus/dbus-sysdeps.c
++++ b/dbus/dbus-sysdeps.c
+@@ -176,6 +176,11 @@ _dbus_setenv (const char *varname,
+ const char*
+ _dbus_getenv (const char *varname)
+ {
++ /* Don't respect any environment variables if the current process is
++ * setuid. This is the equivalent of glibc's __secure_getenv().
++ */
++ if (_dbus_check_setuid ())
++ return NULL;
+ return getenv (varname);
+ }
+
+diff --git a/dbus/dbus-sysdeps.h b/dbus/dbus-sysdeps.h
+index 7817e04..3c374d2 100644
+--- a/dbus/dbus-sysdeps.h
++++ b/dbus/dbus-sysdeps.h
+@@ -97,6 +97,7 @@ typedef struct DBusCredentials DBusCredentials;
+
+ void _dbus_abort (void) _DBUS_GNUC_NORETURN;
+
++dbus_bool_t _dbus_check_setuid (void);
+ const char* _dbus_getenv (const char *varname);
+ dbus_bool_t _dbus_setenv (const char *varname,
+ const char *value);
+--
+1.7.10.4
+
diff -Nru dbus-1.2.24/debian/patches/0002-hardening-Ensure-_dbus_check_setuid-is-initialized-t.patch dbus-1.2.24/debian/patches/0002-hardening-Ensure-_dbus_check_setuid-is-initialized-t.patch
--- dbus-1.2.24/debian/patches/0002-hardening-Ensure-_dbus_check_setuid-is-initialized-t.patch 1970-01-01 01:00:00.000000000 +0100
+++ dbus-1.2.24/debian/patches/0002-hardening-Ensure-_dbus_check_setuid-is-initialized-t.patch 2012-10-04 08:47:17.000000000 +0100
@@ -0,0 +1,36 @@
+From: Colin Walters <walters@verbum.org>
+Date: Thu, 27 Sep 2012 21:35:22 -0400
+Subject: [PATCH 2/5] hardening: Ensure _dbus_check_setuid() is initialized
+ threadsafe manner
+
+This is a highly theoretical concern, but we might as well.
+
+https://bugs.freedesktop.org/show_bug.cgi?id=52202
+
+Origin: upstream, 1.2.30, commit:f7b2ec1b2e39318766938b53511311a0d0a71680
+Bug: https://bugs.freedesktop.org/show_bug.cgi?id=52202
+Bug-CVE: related to CVE-2012-3524
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=689070
+---
+ dbus/dbus-sysdeps-pthread.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/dbus/dbus-sysdeps-pthread.c b/dbus/dbus-sysdeps-pthread.c
+index 46e4204..f21af85 100644
+--- a/dbus/dbus-sysdeps-pthread.c
++++ b/dbus/dbus-sysdeps-pthread.c
+@@ -358,6 +358,11 @@ check_monotonic_clock (void)
+ dbus_bool_t
+ _dbus_threads_init_platform_specific (void)
+ {
++ /* These have static variables, and we need to handle both the case
++ * where dbus_threads_init() has been called and when it hasn't;
++ * so initialize them before any threads are allowed to enter.
++ */
+ check_monotonic_clock ();
++ (void) _dbus_check_setuid ();
+ return dbus_threads_init (&pthread_functions);
+ }
+--
+1.7.10.4
+
diff -Nru dbus-1.2.24/debian/patches/0003-hardening-Remove-activation-helper-handling-for-DBUS.patch dbus-1.2.24/debian/patches/0003-hardening-Remove-activation-helper-handling-for-DBUS.patch
--- dbus-1.2.24/debian/patches/0003-hardening-Remove-activation-helper-handling-for-DBUS.patch 1970-01-01 01:00:00.000000000 +0100
+++ dbus-1.2.24/debian/patches/0003-hardening-Remove-activation-helper-handling-for-DBUS.patch 2012-10-04 08:47:17.000000000 +0100
@@ -0,0 +1,57 @@
+From: Colin Walters <walters@verbum.org>
+Date: Fri, 28 Sep 2012 12:01:56 -0400
+Subject: [PATCH 3/5] hardening: Remove activation helper handling for
+ DBUS_VERBOSE
+
+It's not really useful.
+
+See https://bugs.freedesktop.org/show_bug.cgi?id=52202#c17
+
+Origin: upstream, 1.2.30, commit:b3800b7a666fcefc37eeb25a030241d5809a7246
+Bug: https://bugs.freedesktop.org/show_bug.cgi?id=52202
+Bug-CVE: related to CVE-2012-3524
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=689070
+---
+ bus/activation-helper.c | 14 +-------------
+ 1 file changed, 1 insertion(+), 13 deletions(-)
+
+diff --git a/bus/activation-helper.c b/bus/activation-helper.c
+index baba8f0..bc5ed07 100644
+--- a/bus/activation-helper.c
++++ b/bus/activation-helper.c
+@@ -140,18 +140,12 @@ out_all:
+ return desktop_file;
+ }
+
+-/* Cleares the environment, except for DBUS_VERBOSE and DBUS_STARTER_x */
++/* Clears the environment, except for DBUS_STARTER_x */
+ static dbus_bool_t
+ clear_environment (DBusError *error)
+ {
+- const char *debug_env = NULL;
+ const char *starter_env = NULL;
+
+-#ifdef DBUS_ENABLE_VERBOSE_MODE
+- /* are we debugging */
+- debug_env = _dbus_getenv ("DBUS_VERBOSE");
+-#endif
+-
+ /* we save the starter */
+ starter_env = _dbus_getenv ("DBUS_STARTER_ADDRESS");
+
+@@ -165,12 +159,6 @@ clear_environment (DBusError *error)
+ }
+ #endif
+
+-#ifdef DBUS_ENABLE_VERBOSE_MODE
+- /* restore the debugging environment setting if set */
+- if (debug_env)
+- _dbus_setenv ("DBUS_VERBOSE", debug_env);
+-#endif
+-
+ /* restore the starter */
+ if (starter_env)
+ _dbus_setenv ("DBUS_STARTER_ADDRESS", starter_env);
+--
+1.7.10.4
+
diff -Nru dbus-1.2.24/debian/patches/0004-activation-helper-Ensure-DBUS_STARTER_ADDRESS-is-set.patch dbus-1.2.24/debian/patches/0004-activation-helper-Ensure-DBUS_STARTER_ADDRESS-is-set.patch
--- dbus-1.2.24/debian/patches/0004-activation-helper-Ensure-DBUS_STARTER_ADDRESS-is-set.patch 1970-01-01 01:00:00.000000000 +0100
+++ dbus-1.2.24/debian/patches/0004-activation-helper-Ensure-DBUS_STARTER_ADDRESS-is-set.patch 2012-10-04 08:47:17.000000000 +0100
@@ -0,0 +1,66 @@
+From: Geoffrey Thomas <gthomas@mokafive.com>
+Date: Thu, 27 Sep 2012 22:02:06 -0700
+Subject: [PATCH 4/5] activation-helper: Ensure DBUS_STARTER_ADDRESS is set
+ correctly
+
+The fix for CVE-2012-3524 filters out all environment variables if
+libdbus is used from a setuid program, to prevent various spoofing
+attacks.
+
+Unfortunately, the activation helper is a setuid program linking
+libdbus, and this creates a regression for launched programs using
+DBUS_STARTER_ADDRESS, since it will no longer exist.
+
+Fix this by hardcoding the starter address to the default system bus
+address.
+
+Signed-off-by: Geoffrey Thomas <gthomas@mokafive.com>
+Signed-off-by: Colin Walters <walters@verbum.org>
+Origin: upstream, 1.2.30, commit:c5c747dd7613d777a05ddb663409eeea4e61ec74
+Bug: https://bugs.freedesktop.org/show_bug.cgi?id=52202
+Bug-CVE: related to CVE-2012-3524
+Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=689070
+---
+ bus/activation-helper.c | 16 +++++-----------
+ 1 file changed, 5 insertions(+), 11 deletions(-)
+
+diff --git a/bus/activation-helper.c b/bus/activation-helper.c
+index bc5ed07..bfe832e 100644
+--- a/bus/activation-helper.c
++++ b/bus/activation-helper.c
+@@ -140,15 +140,12 @@ out_all:
+ return desktop_file;
+ }
+
+-/* Clears the environment, except for DBUS_STARTER_x */
++/* Clears the environment, except for DBUS_STARTER_x,
++ * which we hardcode to the system bus.
++ */
+ static dbus_bool_t
+ clear_environment (DBusError *error)
+ {
+- const char *starter_env = NULL;
+-
+- /* we save the starter */
+- starter_env = _dbus_getenv ("DBUS_STARTER_ADDRESS");
+-
+ #ifndef ACTIVATION_LAUNCHER_TEST
+ /* totally clear the environment */
+ if (!_dbus_clearenv ())
+@@ -159,11 +156,8 @@ clear_environment (DBusError *error)
+ }
+ #endif
+
+- /* restore the starter */
+- if (starter_env)
+- _dbus_setenv ("DBUS_STARTER_ADDRESS", starter_env);
+-
+- /* set the type, which must be system if we got this far */
++ /* Ensure the bus is set to system */
++ _dbus_setenv ("DBUS_STARTER_ADDRESS", DBUS_SYSTEM_BUS_DEFAULT_ADDRESS);
+ _dbus_setenv ("DBUS_STARTER_BUS_TYPE", "system");
+
+ return TRUE;
+--
+1.7.10.4
+
diff -Nru dbus-1.2.24/debian/patches/series dbus-1.2.24/debian/patches/series
--- dbus-1.2.24/debian/patches/series 2011-06-12 12:51:34.000000000 +0100
+++ dbus-1.2.24/debian/patches/series 2012-10-04 08:47:17.000000000 +0100
@@ -4,3 +4,7 @@
11-589662-reload-kqueue.patch
12-CVE-2010-4352-reject-deeply-nested-variants.patch
13-629938-_dbus_header_byteswap.patch
+0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch
+0002-hardening-Ensure-_dbus_check_setuid-is-initialized-t.patch
+0003-hardening-Remove-activation-helper-handling-for-DBUS.patch
+0004-activation-helper-Ensure-DBUS_STARTER_ADDRESS-is-set.patch
Reply to: