[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#688512: unblock or tpu: glib2.0/2.33.12+really2.32.4-1



I have just uploaded version 2.33.12+really2.32.4-2 because of a
security vulnerability:

glib2.0 (2.33.12+really2.32.4-2) unstable; urgency=medium

  * Revert link adding for gdbus-object-manager-example. While it is 
    useful to have in /usr/share/doc as an example, it must not be 
    shipped with the system documentation.
  * 20_glib-compile-resources_leak.patch: new patch. Fix a leak 
    introduced in version 2.32.4. Thanks Niels Thykier!
  * SECURITY: add 11_CVE-2012-3524_setuid.patch from upstream. Prevents 
    using DBus in a setuid binary. Fixes CVE-2012-3524.

Attached is the diff between -1 and -2.

Cheers,
-- 
 .''`.      Josselin Mouette
: :' :
`. `'
  `-
Index: debian/control
===================================================================
Index: debian/patches/11_CVE-2012-3524_setuid.patch
===================================================================
--- debian/patches/11_CVE-2012-3524_setuid.patch	(.../2.33.12+really2.32.4-1)	(révision 0)
+++ debian/patches/11_CVE-2012-3524_setuid.patch	(.../2.33.12+really2.32.4-2)	(révision 35895)
@@ -0,0 +1,247 @@
+From 4c2928a54482913cf236bff0e66650a8f47e17ea Mon Sep 17 00:00:00 2001
+From: Colin Walters <walters@verbum.org>
+Date: Wed, 22 Aug 2012 18:26:11 +0000
+Subject: CVE-2012-3524: Hardening for being run in a setuid environment
+
+Some programs attempt to use libglib (or even libgio) when setuid.
+For a long time, GTK+ simply aborted if launched in this
+configuration, but we never had a real policy for GLib.
+
+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.
+
+This patch adds a private function g_check_setuid() which is used to
+first ensure we don't run an external dbus-launch binary if
+DBUS_SESSION_BUS_ADDRESS isn't set.
+
+Second, we also ensure the local VFS is used in this case.  The
+gdaemonvfs extension point will end up talking to the session bus
+which is typically undesirable in a setuid context.
+
+Implementing g_check_setuid() is interesting - 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>
+---
+diff --git a/configure.ac b/configure.ac
+index 584df1d..67ea1a9 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -583,9 +583,20 @@ AC_TRY_COMPILE([#include <dirent.h>], [DIR *dir;],
+ # Checks for library functions.
+ AC_FUNC_VPRINTF
+ AC_FUNC_ALLOCA
+-AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2)
++AC_CHECK_FUNCS(mmap posix_memalign memalign valloc fsync pipe2 issetugid)
+ AC_CHECK_FUNCS(atexit on_exit timegm gmtime_r)
+ 
++AC_CACHE_CHECK([for __libc_enable_secure], glib_cv_have_libc_enable_secure,
++  [AC_TRY_LINK([#include <unistd.h>
++    extern int __libc_enable_secure;],
++    [return __libc_enable_secure;],
++   glib_cv_have_libc_enable_secure=yes,
++   glib_cv_have_libc_enable_secure=no)])
++AS_IF([test x$glib_cv_have_libc_enable_secure = xyes], [
++   AC_DEFINE(HAVE_LIBC_ENABLE_SECURE, 1,
++     [Define if you have the __libc_enable_secure variable (GNU libc, eglibc)])
++])
++
+ AC_CHECK_SIZEOF(char)
+ AC_CHECK_SIZEOF(short)
+ AC_CHECK_SIZEOF(long)
+@@ -984,7 +995,7 @@ AC_MSG_RESULT(unsigned $glib_size_type)
+ 
+ # Check for some functions
+ AC_CHECK_FUNCS(lstat strerror strsignal memmove vsnprintf stpcpy strcasecmp strncasecmp poll getcwd vasprintf setenv unsetenv getc_unlocked readlink symlink fdwalk memmem)
+-AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid)
++AC_CHECK_FUNCS(chown lchmod lchown fchmod fchown link utimes getgrgid getpwuid getresuid)
+ AC_CHECK_FUNCS(getmntent_r setmntent endmntent hasmntopt getfsstat getvfsstat)
+ # Check for high-resolution sleep functions
+ AC_CHECK_FUNCS(splice)
+diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
+index 4aa13b9..96b6343 100644
+--- a/gio/gdbusaddress.c
++++ b/gio/gdbusaddress.c
+@@ -37,6 +37,7 @@
+ #include "giostream.h"
+ #include "gasyncresult.h"
+ #include "gsimpleasyncresult.h"
++#include "glib-private.h"
+ #include "gdbusprivate.h"
+ #include "giomodule-priv.h"
+ #include "gdbusdaemon.h"
+@@ -1023,6 +1024,14 @@ get_session_address_dbus_launch (GError **error)
+   restore_dbus_verbose = FALSE;
+   old_dbus_verbose = NULL;
+ 
++  /* Don't run binaries as root if we're setuid. */
++  if (GLIB_PRIVATE_CALL (g_check_setuid) ())
++    {
++      g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
++		   _("Cannot spawn a message bus when setuid"));
++      goto out;
++    }
++
+   machine_id = _g_dbus_get_machine_id (error);
+   if (machine_id == NULL)
+     {
+diff --git a/gio/gvfs.c b/gio/gvfs.c
+index dda8afb..9afbcec 100644
+--- a/gio/gvfs.c
++++ b/gio/gvfs.c
+@@ -23,6 +23,7 @@
+ #include "config.h"
+ #include <string.h>
+ #include "gvfs.h"
++#include "glib-private.h"
+ #include "glocalvfs.h"
+ #include "gresourcefile.h"
+ #include "giomodule-priv.h"
+@@ -191,6 +192,8 @@ g_vfs_parse_name (GVfs       *vfs,
+ GVfs *
+ g_vfs_get_default (void)
+ {
++  if (GLIB_PRIVATE_CALL (g_check_setuid) ())
++    return g_vfs_get_local ();
+   return _g_io_module_get_default (G_VFS_EXTENSION_POINT_NAME,
+ 				   "GIO_USE_VFS",
+ 				   (GIOModuleVerifyFunc)g_vfs_is_active);
+diff --git a/glib/genviron.c b/glib/genviron.c
+index 59a8bbe..9525cf0 100644
+--- a/glib/genviron.c
++++ b/glib/genviron.c
+@@ -40,6 +40,7 @@
+ #include <windows.h>
+ #endif
+ 
++#include "glib-private.h"
+ #include "gmem.h"
+ #include "gmessages.h"
+ #include "gstrfuncs.h"
+diff --git a/glib/glib-private.c b/glib/glib-private.c
+index 3946e77..3506782 100644
+--- a/glib/glib-private.c
++++ b/glib/glib-private.c
+@@ -38,7 +38,9 @@ glib__private__ (void)
+     g_wakeup_signal,
+     g_wakeup_acknowledge,
+ 
+-    g_get_worker_context
++    g_get_worker_context,
++
++    g_check_setuid
+   };
+ 
+   return &table;
+diff --git a/glib/glib-private.h b/glib/glib-private.h
+index fde0be8..87da6f3 100644
+--- a/glib/glib-private.h
++++ b/glib/glib-private.h
+@@ -25,6 +25,8 @@
+ 
+ G_GNUC_INTERNAL
+ GMainContext *          g_get_worker_context            (void);
++G_GNUC_INTERNAL
++gboolean                g_check_setuid                  (void);
+ 
+ #define GLIB_PRIVATE_CALL(symbol) (glib__private__()->symbol)
+ 
+@@ -40,6 +42,8 @@ typedef struct {
+   /* See gmain.c */
+   GMainContext *        (* g_get_worker_context)        (void);
+   /* Add other private functions here, initialize them in glib-private.c */
++
++  gboolean              (* g_check_setuid)              (void);
+ } GLibPrivateVTable;
+ 
+ GLibPrivateVTable *glib__private__ (void);
+diff --git a/glib/gutils.c b/glib/gutils.c
+index 38b5e44..f8a38d1 100644
+--- a/glib/gutils.c
++++ b/glib/gutils.c
+@@ -2409,3 +2409,60 @@ g_get_tmp_dir (void)
+ }
+ 
+ #endif
++
++/* Private API:
++ *
++ * 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
++ */ 
++gboolean
++g_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 ();
++#elif defined(G_OS_UNIX)
++  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 gsize check_setuid_initialised;
++  static gboolean is_setuid;
++
++  if (g_once_init_enter (&check_setuid_initialised))
++    {
++#ifdef HAVE_GETRESUID
++      /* These aren't in the header files, so we prototype them here.
++       */
++      int getresuid(uid_t *ruid, uid_t *euid, uid_t *suid);
++      int getresgid(gid_t *rgid, gid_t *egid, gid_t *sgid);
++      
++      if (getresuid (&ruid, &euid, &suid) != 0 ||
++          getresgid (&rgid, &egid, &sgid) != 0)
++#endif /* HAVE_GETRESUID */
++        {
++          suid = ruid = getuid ();
++          sgid = rgid = getgid ();
++          euid = geteuid ();
++          egid = getegid ();
++        }
++
++      is_setuid = (ruid != euid || ruid != suid ||
++                   rgid != egid || rgid != sgid);
++
++      g_once_init_leave (&check_setuid_initialised, 1);
++    }
++  return is_setuid;
++#else
++  return FALSE;
++#endif
++}
+--
+cgit v0.9.0.2
Index: debian/patches/20_glib-compile-resources_leak.patch
===================================================================
--- debian/patches/20_glib-compile-resources_leak.patch	(.../2.33.12+really2.32.4-1)	(révision 0)
+++ debian/patches/20_glib-compile-resources_leak.patch	(.../2.33.12+really2.32.4-2)	(révision 35895)
@@ -0,0 +1,36 @@
+Index: glib2.0-2.33.12+really2.32.4/gio/glib-compile-resources.c
+===================================================================
+--- glib2.0-2.33.12+really2.32.4.orig/gio/glib-compile-resources.c	2012-07-14 22:33:11.000000000 +0200
++++ glib2.0-2.33.12+really2.32.4/gio/glib-compile-resources.c	2012-09-28 21:32:32.168548276 +0200
+@@ -272,7 +272,6 @@ end_element (GMarkupParseContext  *conte
+       if (state->preproc_options)
+         {
+           gchar **options;
+-          gchar *stderr_child = NULL;
+           guint i;
+           gboolean xml_stripblanks = FALSE;
+           gboolean to_pixdata = FALSE;
+@@ -298,6 +297,7 @@ end_element (GMarkupParseContext  *conte
+           if (xml_stripblanks && xmllint != NULL)
+             {
+               gchar *argv[8];
++              gchar *stderr_child = NULL;
+               int status, fd, argc;
+ 
+               tmp_file = g_strdup ("resource-XXXXXXXX");
+@@ -336,6 +336,7 @@ end_element (GMarkupParseContext  *conte
+                 {
+                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+                                _("Error processing input file with xmllint:\n%s"), stderr_child);
++                  g_free (stderr_child);
+                   goto cleanup;
+                 }
+ #endif
+@@ -392,6 +393,7 @@ end_element (GMarkupParseContext  *conte
+                 {
+                   g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED,
+ 			       _("Error processing input file with to-pixdata:\n%s"), stderr_child);
++                  g_free (stderr_child);
+                   goto cleanup;
+                 }
+ #endif
Index: debian/patches/series
===================================================================
--- debian/patches/series	(.../2.33.12+really2.32.4-1)	(révision 35895)
+++ debian/patches/series	(.../2.33.12+really2.32.4-2)	(révision 35895)
@@ -4,6 +4,8 @@
 04_homedir_env.patch
 05_run-gio-tests-with-a-dbus-session.patch
 10_gdbus_race.patch
+11_CVE-2012-3524_setuid.patch
+20_glib-compile-resources_leak.patch
 61_glib-compile-binaries-path.patch
 90_gio-modules-multiarch-compat.patch
 91_revert_schema_path_warning.patch
Index: debian/libglib2.0-doc.links
===================================================================
--- debian/libglib2.0-doc.links	(.../2.33.12+really2.32.4-1)	(révision 35895)
+++ debian/libglib2.0-doc.links	(.../2.33.12+really2.32.4-2)	(révision 35895)
@@ -2,4 +2,3 @@
 usr/share/doc/libglib2.0-doc/gio usr/share/gtk-doc/html/gio
 usr/share/doc/libglib2.0-doc/glib usr/share/gtk-doc/html/glib
 usr/share/doc/libglib2.0-doc/gobject usr/share/gtk-doc/html/gobject
-usr/share/doc/libglib2.0-doc/gdbus-object-manager-example usr/share/gtk-doc/html/gdbus-object-manager-example
Index: debian/changelog
===================================================================
--- debian/changelog	(.../2.33.12+really2.32.4-1)	(révision 35895)
+++ debian/changelog	(.../2.33.12+really2.32.4-2)	(révision 35895)
@@ -1,3 +1,15 @@
+glib2.0 (2.33.12+really2.32.4-2) unstable; urgency=medium
+
+  * Revert link adding for gdbus-object-manager-example. While it is 
+    useful to have in /usr/share/doc as an example, it must not be 
+    shipped with the system documentation.
+  * 20_glib-compile-resources_leak.patch: new patch. Fix a leak 
+    introduced in version 2.32.4. Thanks Niels Thykier!
+  * SECURITY: add 11_CVE-2012-3524_setuid.patch from upstream. Prevents 
+    using DBus in a setuid binary. Fixes CVE-2012-3524.
+
+ -- Josselin Mouette <joss@debian.org>  Sat, 06 Oct 2012 01:15:16 +0200
+
 glib2.0 (2.33.12+really2.32.4-1) unstable; urgency=low
 
   * New upstream bugfix release.

Reply to: