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 +- * Author: Stef Walter ++ * Author: Steve Grubb + */ + + #include "config.h" + + #include "gkd-capability.h" + +-#ifdef HAVE_LIBCAP +-#include ++#ifdef HAVE_LIBCAPNG ++#include + #endif + + #include +-#include +-#include + #include + +-/* 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 - 2.91.4-3 +- Use file system based capabilities instead of suid bit (#668831) + * Fri Jan 7 2011 Matthias Clasen - 2.91.4-2 - Rebuild against new gtk