summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--configure.ac2
-rw-r--r--dbus/dbus-keyring.c7
-rw-r--r--dbus/dbus-sysdeps-unix.c74
-rw-r--r--dbus/dbus-sysdeps-win.c6
-rw-r--r--dbus/dbus-sysdeps.c5
-rw-r--r--dbus/dbus-sysdeps.h1
6 files changed, 94 insertions, 1 deletions
diff --git a/configure.ac b/configure.ac
index e2c9bdf7..b0f2ec20 100644
--- a/configure.ac
+++ b/configure.ac
@@ -595,7 +595,7 @@ AC_DEFINE_UNQUOTED([DBUS_USE_SYNC], [$have_sync], [Use the gcc __sync extension]
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 setlocale localeconv strtoll strtoull)
+AC_CHECK_FUNCS(vsnprintf vasprintf nanosleep usleep setenv clearenv unsetenv socketpair getgrouplist fpathconf setrlimit poll setlocale localeconv strtoll strtoull issetugid getresuid)
AC_CHECK_HEADERS([syslog.h])
if test "x$ac_cv_header_syslog_h" = "xyes"; then
diff --git a/dbus/dbus-keyring.c b/dbus/dbus-keyring.c
index 23b9df5a..3b9ce315 100644
--- a/dbus/dbus-keyring.c
+++ b/dbus/dbus-keyring.c
@@ -717,6 +717,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 cef8bd31..b4ecc96e 100644
--- a/dbus/dbus-sysdeps-unix.c
+++ b/dbus/dbus-sysdeps-unix.c
@@ -3434,6 +3434,13 @@ _dbus_get_autolaunch_address (const char *scope,
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;
@@ -3551,6 +3558,13 @@ _dbus_lookup_launchd_socket (DBusString *socket_path,
_DBUS_ASSERT_ERROR_IS_CLEAR (error);
+ if (_dbus_check_setuid ())
+ {
+ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Unable to find launchd socket when setuid");
+ return FALSE;
+ }
+
i = 0;
argv[i] = "launchctl";
++i;
@@ -3591,6 +3605,13 @@ _dbus_lookup_session_address_launchd (DBusString *address, DBusError *error)
dbus_bool_t valid_socket;
DBusString socket_path;
+ if (_dbus_check_setuid ())
+ {
+ dbus_set_error_const (error, DBUS_ERROR_NOT_SUPPORTED,
+ "Unable to find launchd socket when setuid");
+ return FALSE;
+ }
+
if (!_dbus_string_init (&socket_path))
{
_DBUS_SET_OOM (error);
@@ -4086,4 +4107,57 @@ _dbus_close_all (void)
close (i);
}
+/**
+ * **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 397520af..bc4951b5 100644
--- a/dbus/dbus-sysdeps-win.c
+++ b/dbus/dbus-sysdeps-win.c
@@ -3632,6 +3632,12 @@ _dbus_path_is_absolute (const DBusString *filename)
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 861bfec9..04fb8d76 100644
--- a/dbus/dbus-sysdeps.c
+++ b/dbus/dbus-sysdeps.c
@@ -182,6 +182,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 4052cda9..eee91608 100644
--- a/dbus/dbus-sysdeps.h
+++ b/dbus/dbus-sysdeps.h
@@ -87,6 +87,7 @@ typedef struct DBusPipe DBusPipe;
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);