Mageia Bugzilla – Attachment 2794 Details for
Bug 7474
dbus new security issue CVE-2012-3524
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
Log In
[x]
|
New Account
|
Forgot Password
[patch]
0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch
0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch (text/plain), 6.43 KB, created by
David Walser
on 2012-09-13 21:45:32 CEST
(
hide
)
Description:
0001-CVE-2012-3524-Don-t-access-environment-variables-or-.patch
Filename:
MIME Type:
Creator:
David Walser
Created:
2012-09-13 21:45:32 CEST
Size:
6.43 KB
patch
obsolete
>From dd07020822105838179b8825af19ffd5aeedf934 Mon Sep 17 00:00:00 2001 >From: Colin Walters <walters@verbum.org> >Date: Wed, 22 Aug 2012 10:03:34 -0400 >Subject: [PATCH] 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> >--- > 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.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.1 >
From dd07020822105838179b8825af19ffd5aeedf934 Mon Sep 17 00:00:00 2001 From: Colin Walters <walters@verbum.org> Date: Wed, 22 Aug 2012 10:03:34 -0400 Subject: [PATCH] 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> --- 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.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.1
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 7474
: 2794