From 4ff10fee86b40ac30ca1f412e4d6ac8b4d20d70e Mon Sep 17 00:00:00 2001 From: Alexander Larsson Date: Sun, 8 Feb 2015 23:37:47 +0100 Subject: [PATCH] Add support for --with-priv-mode=caps This allows you to set the privs for the helper via file capabilities instead of setuid. You can also set the mode to none, but then you have to manually set either setuid or filecaps (for instance via a packaging script). --- Makefile.am | 6 ++++++ configure.ac | 9 +++++++++ xdg-app-helper.c | 15 +++++++++------ 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/Makefile.am b/Makefile.am index 9fdd0b2d..8f7a5d4c 100644 --- a/Makefile.am +++ b/Makefile.am @@ -97,8 +97,14 @@ xdg_app_LDADD = $(BASE_LIBS) $(OSTREE_LIBS) $(SOUP_LIBS) xdg_app_CFLAGS = $(BASE_CFLAGS) $(OSTREE_CFLAGS) $(SOUP_CFLAGS) install-exec-hook: +if PRIV_MODE_SETUID $(SUDO_BIN) chown root $(DESTDIR)$(bindir)/xdg-app-helper $(SUDO_BIN) chmod u+s $(DESTDIR)$(bindir)/xdg-app-helper +else +if PRIV_MODE_FILECAPS + $(SUDO_BIN) setcap cap_sys_admin,cap_mknod+ep /gnome/bin/xdg-app-helper +endif +endif completiondir = $(datadir)/bash-completion/completions completion_DATA = completion/xdg-app diff --git a/configure.ac b/configure.ac index fa5a9819..3819c926 100644 --- a/configure.ac +++ b/configure.ac @@ -48,6 +48,15 @@ PKG_CHECK_MODULES(OSTREE, [libgsystem >= 2015.1 ostree-1 >= 2015.1]) AC_SUBST(OSTREE_CFLAGS) AC_SUBST(OSTREE_LIBS) +AC_ARG_WITH(priv-mode, + AS_HELP_STRING([--with-priv-mode=setuid/caps/none], + [How to gain privileges]), + [], + [with_priv_mode="setuid"]) + +AM_CONDITIONAL(PRIV_MODE_SETUID, test "x$with_priv_mode" = "xsetuid") +AM_CONDITIONAL(PRIV_MODE_FILECAPS, test "x$with_priv_mode" = "xcaps") + AC_ARG_ENABLE(sudo, AS_HELP_STRING([--enable-sudo],[Use sudo to set setuid flags on binaries during install]), [SUDO_BIN="sudo"], [SUDO_BIN=""]) diff --git a/xdg-app-helper.c b/xdg-app-helper.c index 1450f14f..0f494729 100644 --- a/xdg-app-helper.c +++ b/xdg-app-helper.c @@ -1074,13 +1074,16 @@ acquire_caps (void) struct __user_cap_header_struct hdr; struct __user_cap_data_struct data; - /* Tell kernel not clear capabilities when dropping root */ - if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) - die_with_error ("prctl(PR_SET_KEEPCAPS) failed"); + if (getuid () != geteuid ()) + { + /* Tell kernel not clear capabilities when dropping root */ + if (prctl (PR_SET_KEEPCAPS, 1, 0, 0, 0) < 0) + die_with_error ("prctl(PR_SET_KEEPCAPS) failed"); - /* Drop root uid, but retain the required permitted caps */ - if (setuid (getuid ()) < 0) - die_with_error ("unable to drop privs"); + /* Drop root uid, but retain the required permitted caps */ + if (setuid (getuid ()) < 0) + die_with_error ("unable to drop privs"); + } memset (&hdr, 0, sizeof(hdr)); hdr.version = _LINUX_CAPABILITY_VERSION;