diff options
-rw-r--r-- | Makefile.am | 11 | ||||
-rw-r--r-- | configure.ac | 4 | ||||
-rw-r--r-- | src/bus-proxyd/bus-proxyd.c | 22 | ||||
-rw-r--r-- | src/shared/capability.c | 18 | ||||
-rw-r--r-- | src/shared/capability.h | 2 | ||||
-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 +) |