summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am11
-rw-r--r--configure.ac4
-rw-r--r--src/bus-proxyd/bus-proxyd.c22
-rw-r--r--src/shared/capability.c18
-rw-r--r--src/shared/capability.h2
-rw-r--r--units/systemd-bus-proxyd@.service.m4.in (renamed from units/systemd-bus-proxyd@.service.in)2
-rw-r--r--units/user@.service.m4.in (renamed from units/user@.service.in)4
7 files changed, 60 insertions, 3 deletions
diff --git a/Makefile.am b/Makefile.am
index 7b43733eb1..78cf4a94f0 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -591,7 +591,7 @@ EXTRA_DIST += \
units/systemd-fsck@.service.in \
units/systemd-fsck-root.service.in \
units/systemd-machine-id-commit.service.in \
- units/user@.service.in \
+ units/user@.service.m4.in \
units/debug-shell.service.in \
units/systemd-suspend.service.in \
units/quotaon.service.in \
@@ -2579,9 +2579,16 @@ dist_userunit_DATA += \
endif
EXTRA_DIST += \
- units/systemd-bus-proxyd@.service.in \
+ units/systemd-bus-proxyd@.service.m4.in \
units/user/systemd-bus-proxyd@.service.in
+if HAVE_SMACK
+bus-proxyd-set-cap-hook:
+ $(SETCAP) cap_mac_admin+ei $(DESTDIR)$(rootlibexecdir)/systemd-bus-proxyd
+
+INSTALL_EXEC_HOOKS += bus-proxyd-set-cap-hook
+endif
+
# ------------------------------------------------------------------------------
systemd_tty_ask_password_agent_SOURCES = \
src/tty-ask-password-agent/tty-ask-password-agent.c
diff --git a/configure.ac b/configure.ac
index 356a3c3d67..94b4a0233a 100644
--- a/configure.ac
+++ b/configure.ac
@@ -90,6 +90,8 @@ AC_PATH_PROG([XSLTPROC], [xsltproc])
AC_PATH_PROG([QUOTAON], [quotaon], [/usr/sbin/quotaon], [$PATH:/usr/sbin:/sbin])
AC_PATH_PROG([QUOTACHECK], [quotacheck], [/usr/sbin/quotacheck], [$PATH:/usr/sbin:/sbin])
+AC_PATH_PROG([SETCAP], [setcap], [/usr/sbin/setcap], [$PATH:/usr/sbin:/sbin])
+
AC_PATH_PROG([KILL], [kill], [/usr/bin/kill], [$PATH:/usr/sbin:/sbin])
AC_PATH_PROG([KMOD], [kmod], [/usr/bin/kmod], [$PATH:/usr/sbin:/sbin])
@@ -674,6 +676,8 @@ if test "x${have_smack}" = xyes ; then
AC_DEFINE(HAVE_SMACK, 1, [Define if SMACK is available])
fi
+AM_CONDITIONAL([HAVE_SMACK], [test "x$have_smack" = "xyes"])
+
# ------------------------------------------------------------------------------
AC_ARG_ENABLE([gcrypt],
AS_HELP_STRING([--disable-gcrypt],[Disable optional GCRYPT support]),
diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c
index 42fb0da0ef..5d304538fd 100644
--- a/src/bus-proxyd/bus-proxyd.c
+++ b/src/bus-proxyd/bus-proxyd.c
@@ -46,6 +46,7 @@
#include "capability.h"
#include "bus-policy.h"
#include "bus-control.h"
+#include "smack-util.h"
static char *arg_address = NULL;
static char *arg_command_line_buffer = NULL;
@@ -1235,6 +1236,23 @@ static int patch_sender(sd_bus *a, sd_bus_message *m) {
return 0;
}
+static int mac_smack_apply_label_and_drop_cap_mac_admin(pid_t its_pid, const char *new_label) {
+#ifdef HAVE_SMACK
+ int r = 0, k;
+
+ if (!mac_smack_use())
+ return 0;
+
+ if (new_label && its_pid > 0)
+ r = mac_smack_apply_pid(its_pid, new_label);
+
+ k = drop_capability(CAP_MAC_ADMIN);
+ return r < 0 ? r : k;
+#else
+ return 0;
+#endif
+}
+
int main(int argc, char *argv[]) {
_cleanup_bus_close_unref_ sd_bus *a = NULL, *b = NULL;
@@ -1274,6 +1292,10 @@ int main(int argc, char *argv[]) {
if (is_unix) {
(void) getpeercred(in_fd, &ucred);
(void) getpeersec(in_fd, &peersec);
+
+ r = mac_smack_apply_label_and_drop_cap_mac_admin(getpid(), peersec);
+ if (r < 0)
+ log_warning_errno(r, "Failed to set SMACK label (%s) and drop CAP_MAC_ADMIN: %m", peersec);
}
if (arg_drop_privileges) {
diff --git a/src/shared/capability.c b/src/shared/capability.c
index 5d156ab3cd..65d7e038a7 100644
--- a/src/shared/capability.c
+++ b/src/shared/capability.c
@@ -271,3 +271,21 @@ int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilities) {
return 0;
}
+
+int drop_capability(cap_value_t cv) {
+ _cleanup_cap_free_ cap_t tmp_cap = NULL;
+
+ tmp_cap = cap_get_proc();
+ if (!tmp_cap)
+ return -errno;
+
+ if ((cap_set_flag(tmp_cap, CAP_INHERITABLE, 1, &cv, CAP_CLEAR) < 0) ||
+ (cap_set_flag(tmp_cap, CAP_PERMITTED, 1, &cv, CAP_CLEAR) < 0) ||
+ (cap_set_flag(tmp_cap, CAP_EFFECTIVE, 1, &cv, CAP_CLEAR) < 0))
+ return -errno;
+
+ if (cap_set_proc(tmp_cap) < 0)
+ return -errno;
+
+ return 0;
+}
diff --git a/src/shared/capability.h b/src/shared/capability.h
index 3e6d9995f5..6f2f6f997d 100644
--- a/src/shared/capability.h
+++ b/src/shared/capability.h
@@ -34,6 +34,8 @@ int capability_bounding_set_drop_usermode(uint64_t drop);
int drop_privileges(uid_t uid, gid_t gid, uint64_t keep_capabilites);
+int drop_capability(cap_value_t cv);
+
DEFINE_TRIVIAL_CLEANUP_FUNC(cap_t, cap_free);
#define _cleanup_cap_free_ _cleanup_(cap_freep)
diff --git a/units/systemd-bus-proxyd@.service.in b/units/systemd-bus-proxyd@.service.m4.in
index 23b5ffa072..3f3ab64dee 100644
--- a/units/systemd-bus-proxyd@.service.in
+++ b/units/systemd-bus-proxyd@.service.m4.in
@@ -14,7 +14,7 @@ Description=Legacy D-Bus Protocol Compatibility Daemon
# space available for this.
ExecStart=@rootlibexecdir@/systemd-bus-proxyd --drop-privileges --address=kernel:path=/sys/fs/kdbus/0-system/bus xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
NotifyAccess=main
-CapabilityBoundingSet=CAP_IPC_OWNER CAP_SETUID CAP_SETGID CAP_SETPCAP
+CapabilityBoundingSet=CAP_IPC_OWNER CAP_SETUID CAP_SETGID CAP_SETPCAP m4_ifdef(`HAVE_SMACK', CAP_MAC_ADMIN )
PrivateTmp=yes
PrivateDevices=yes
PrivateNetwork=yes
diff --git a/units/user@.service.in b/units/user@.service.m4.in
index 1e21d51aae..340c02b59b 100644
--- a/units/user@.service.in
+++ b/units/user@.service.m4.in
@@ -17,3 +17,7 @@ ExecStart=-@rootlibexecdir@/systemd --user
Slice=user-%i.slice
KillMode=mixed
Delegate=yes
+m4_ifdef(`HAVE_SMACK',
+Capabilities=cap_mac_admin=i
+SecureBits=keep-caps
+)