[gnome-keyring] - Use file system based capabilities instead of suid bit (#668831)
Tomas Bzatek
tbzatek at fedoraproject.org
Mon Jan 17 15:02:23 UTC 2011
commit e41c396c8901bc8e3746e12d878fccc0dc584303
Author: Tomas Bzatek <tbzatek at redhat.com>
Date: Mon Jan 17 16:02:15 2011 +0100
- Use file system based capabilities instead of suid bit (#668831)
file-caps.patch | 186 ++++++++++++++++++++++++++++++++++++++++++++++++++++
gnome-keyring.spec | 14 ++++-
2 files changed, 198 insertions(+), 2 deletions(-)
---
diff --git a/file-caps.patch b/file-caps.patch
new file mode 100644
index 0000000..de99c34
--- /dev/null
+++ b/file-caps.patch
@@ -0,0 +1,186 @@
+diff -urp gnome-keyring-2.91.4.orig/configure.in gnome-keyring-2.91.4/configure.in
+--- gnome-keyring-2.91.4.orig/configure.in 2011-01-13 08:24:04.000000000 -0500
++++ gnome-keyring-2.91.4/configure.in 2011-01-13 09:29:54.000000000 -0500
+@@ -447,19 +447,19 @@ if test "$ASN1PARSER" = "no" ; then
+ fi
+
+ # -------------------------------------------------------------------
+-# libcap2
++# libcap-ng
+ #
+
+-AC_CHECK_LIB([cap], [cap_get_proc], have_libcap="yes", have_libcap="no")
++AC_CHECK_LIB([cap-ng], [capng_clear], have_libcapng="yes", have_libcapng="no")
+
+-if test $have_libcap = yes; then
+- AC_DEFINE(HAVE_LIBCAP, 1, [Have libcap2 package, libcap library])
+- DAEMON_LIBS="$DAEMON_LIBS -lcap"
++if test $have_libcapng = yes; then
++ AC_DEFINE(HAVE_LIBCAPNG, 1, [Have libcap-ng package, libcap-ng library])
++ DAEMON_LIBS="$DAEMON_LIBS -lcap-ng"
+ else
+- AC_MSG_WARN([libcap2 (or development headers) is not installed])
++ AC_MSG_WARN([libcap-ng (or development headers) is not installed])
+ fi
+
+-libcap_status=$have_libcap
++libcapng_status=$have_libcapng
+
+ # --------------------------------------------------------------------
+ # Debug mode
+@@ -748,7 +748,7 @@ ui/tests/Makefile
+ echo
+ echo "OPTIONAL DEPENDENCIES"
+ echo " PAM: $pam_status"
+-echo " Linux capabilities: $libcap_status"
++echo " Linux capabilities: $libcapng_status"
+ echo
+ echo "CONFIGURATION"
+ echo " SSH Agent: $ssh_status"
+diff -urp gnome-keyring-2.91.4.orig/daemon/gkd-capability.c gnome-keyring-2.91.4/daemon/gkd-capability.c
+--- gnome-keyring-2.91.4.orig/daemon/gkd-capability.c 2011-01-13 08:24:04.000000000 -0500
++++ gnome-keyring-2.91.4/daemon/gkd-capability.c 2011-01-13 09:30:12.000000000 -0500
+@@ -1,7 +1,7 @@
+ /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+ /* gkd-capability.c - the security-critical initial phase of the daemon
+ *
+- * Copyright (C) 2010 Yaron Sheffer
++ * Copyright (C) 2011 Steve Grubb
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as
+@@ -18,102 +18,62 @@
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ * 02111-1307, USA.
+ *
+- * Author: Yaron Sheffer <yaronf at gmx.com>
+- * Author: Stef Walter <stef at thewalter.net>
++ * Author: Steve Grubb <sgrubb at redhat.com>
+ */
+
+ #include "config.h"
+
+ #include "gkd-capability.h"
+
+-#ifdef HAVE_LIBCAP
+-#include <sys/capability.h>
++#ifdef HAVE_LIBCAPNG
++#include <cap-ng.h>
+ #endif
+
+ #include <stdio.h>
+-#include <unistd.h>
+-#include <sys/types.h>
+ #include <stdlib.h>
+
+-/* Security note: this portion of the code is extremely sensitive.
+- * DO NOT add any other include files.
+- */
+-
+ /*
+ * No logging, no gettext
+ */
+ static void
+ early_error (const char *err_string)
+ {
+- fprintf (stderr, "gnome-keyring-daemon: %s\n", err_string);
+-}
+-
+-static void
+-drop_privileges (void)
+-{
+- uid_t orig_uid;
+- gid_t orig_gid;
+-
+- orig_uid = getuid ();
+- orig_gid = getgid ();
+-
+- /* This is permanent, you cannot go back to root */
+- setgid (orig_gid);
+- setuid (orig_uid);
+-
+- /*
+- * Check that the switch was ok
+- * We do not allow programs to run without the drop being
+- * successful as this would possibly run the program
+- * using root-privs, when that is not what we want
+- */
+- if ((getegid () != orig_gid) || (geteuid () != orig_uid)) {
+- early_error ("failed to drop privileges, aborting");
+- exit (1);
+- }
++ fprintf (stderr, "gnome-keyring-daemon: %s, aborting\n", err_string);
++ exit (1);
+ }
+
+ /*
+- * Try to obtain the CAP_IPC_LOCK Linux capability.
+- * Then, whether or not this is successful, drop root
+- * privileges to run as the invoking user. The application is aborted
+- * if for any reason we are unable to drop privileges. Note: even gettext
+- * is unavailable!
++ * This program needs the CAP_IPC_LOCK posix capability.
++ * We want to allow either setuid root or file system based capabilies
++ * to work. If file system based capabilities, this is a no-op unless
++ * the root user is running the program. In that case we just drop
++ * capabilities down to IPC_LOCK. If we are setuid root, then change to the
++ * invoking user retaining just the IPC_LOCK capability. The application
++ * is aborted if for any reason we are unable to drop privileges.
++ * Note: even gettext is unavailable!
+ */
+ void
+ gkd_capability_obtain_capability_and_drop_privileges (void)
+ {
+-#ifdef HAVE_LIBCAP
+- cap_t caps;
+- cap_value_t cap_list[1];
+-
+- caps = cap_get_proc ();
+- if (caps == NULL) {
+- early_error ("capability state cannot be allocated");
+- goto drop;
+- }
+-
+- cap_list[0] = CAP_IPC_LOCK;
+- if (cap_set_flag (caps, CAP_EFFECTIVE, 1, cap_list, CAP_SET) == -1) {
+- early_error ("error when manipulating capability sets");
+- goto drop;
+- }
+-
+- if (cap_set_proc (caps) == -1) {
+- /* Only warn when it's root that's running */
+- if (getuid () == 0)
+- early_error ("cannot apply capabilities to process");
+- goto drop;
+- }
+-
+- if (cap_free (caps) == -1) {
+- early_error ("failed to free capability structure");
+- goto drop;
++#ifdef HAVE_LIBCAPNG
++ capng_get_caps_process ();
++ switch (capng_have_capabilities (CAPNG_SELECT_CAPS))
++ {
++ case CAPNG_FULL:
++ /* We are either setuid root or the root user */
++ capng_clear (CAPNG_SELECT_CAPS);
++ capng_update (CAPNG_ADD,
++ CAPNG_EFFECTIVE|CAPNG_PERMITTED,
++ CAP_IPC_LOCK);
++ if (capng_change_id (getuid (), getgid (), 0))
++ early_error ("failed dropping capabilities");
++ break;
++ case CAPNG_FAIL:
++ case CAPNG_NONE:
++ early_error ("error getting process capabilities");
++ break;
++ case CAPNG_PARTIAL: /* File system based capabilities */
++ break;
+ }
+-drop:
+-
+ #endif
+- /* Now finally drop the suid by becoming the invoking user */
+- if (geteuid () != getuid() || getegid () != getgid ())
+- drop_privileges ();
+ }
diff --git a/gnome-keyring.spec b/gnome-keyring.spec
index 3124e50..f96e49b 100644
--- a/gnome-keyring.spec
+++ b/gnome-keyring.spec
@@ -7,7 +7,7 @@
Summary: Framework for managing passwords and other secrets
Name: gnome-keyring
Version: 2.91.4
-Release: 2%{?dist}
+Release: 3%{?dist}
License: GPLv2+ and LGPLv2+
Group: System Environment/Libraries
#VCS: git:git://git.gnome.org/gnome-keyring
@@ -18,6 +18,9 @@ URL: http://www.gnome.org
# http://bugs.gnome.org/598494
Patch3: gnome-keyring-2.28.1-nopass.patch
+# why is gnome-keyring-daemon setuid root?
+# https://bugzilla.redhat.com/show_bug.cgi?id=668831
+Patch4: file-caps.patch
BuildRequires: glib2-devel >= %{glib2_version}
BuildRequires: gtk3-devel >= %{gtk3_version}
@@ -31,6 +34,7 @@ BuildRequires: intltool
BuildRequires: libtasn1-tools
BuildRequires: libgnome-keyring-devel
BuildRequires: gtk-doc
+BuildRequires: libcap-ng-devel
# for smooth transition since the core was split
Requires: libgnome-keyring
@@ -68,6 +72,7 @@ automatically unlock the "login" keyring when the user logs in.
%prep
%setup -q -n gnome-keyring-%{version}
%patch3 -p1 -b .no-pass
+%patch4 -p1 -b .file-caps
# Enable daemon autostart in XFCE
for i in daemon/*.desktop.in.in; do
@@ -121,7 +126,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas
%{_libdir}/pkcs11/*.so
%{_libdir}/gnome-keyring/devel/*.so
# GPL
-%{_bindir}/*
+%attr(0755,root,root) %caps(cap_ipc_lock=ep) %{_bindir}/gnome-keyring-daemon
+%{_bindir}/gnome-keyring
+%{_bindir}/gnome-keyring-3
%{_libexecdir}/*
%{_datadir}/dbus-1/services/*.service
%{_datadir}/gcr-3
@@ -145,6 +152,9 @@ glib-compile-schemas %{_datadir}/glib-2.0/schemas
%changelog
+* Mon Jan 17 2011 Tomas Bzatek <tbzatek at redhat.com> - 2.91.4-3
+- Use file system based capabilities instead of suid bit (#668831)
+
* Fri Jan 7 2011 Matthias Clasen <mclasen at redhat.com> - 2.91.4-2
- Rebuild against new gtk
More information about the scm-commits
mailing list