When dbus client connects to systemd-bus-proxyd through Unix domain socket proxy takes client's smack label and sets for itself.
It is done before and independent of dropping privileges. The reason of such soluton is fact that tests of access rights performed by lsm may take place inside kernel, not only in userspace of recipient of message. The bus-proxyd needs CAP_MAC_ADMIN to manipulate its label. In case of systemd running in system mode, CAP_MAC_ADMIN should be added to CapabilityBoundingSet in service file of bus-proxyd. In case of systemd running in user mode ('systemd --user') it can be achieved by addition Capabilities=cap_mac_admin=i and SecureBits=keep-caps to user@.service file and setting cap_mac_admin+ei on bus-proxyd binary. Change-Id: I0acb5ec0d9ce4aecf25ddb0ca0e137b7a187a02f --- Makefile.am | 4 ++-- src/bus-proxyd/bus-proxyd.c | 17 +++++++++++++++++ src/shared/capability.c | 18 ++++++++++++++++++ src/shared/capability.h | 2 ++ units/systemd-bus-pro...@.service.in | 22 ---------------------- units/systemd-bus-pro...@.service.m4.in | 22 ++++++++++++++++++++++ units/u...@.service.in | 19 ------------------- units/u...@.service.m4.in | 23 +++++++++++++++++++++++ 8 files changed, 84 insertions(+), 43 deletions(-) delete mode 100644 units/systemd-bus-pro...@.service.in create mode 100644 units/systemd-bus-pro...@.service.m4.in delete mode 100644 units/u...@.service.in create mode 100644 units/u...@.service.m4.in diff --git a/Makefile.am b/Makefile.am index 701666c..e9db1f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -588,7 +588,7 @@ EXTRA_DIST += \ units/user/systemd-exit.service.in \ units/systemd-f...@.service.in \ units/systemd-fsck-root.service.in \ - units/u...@.service.in \ + units/u...@.service.m4.in \ units/debug-shell.service.in \ units/systemd-suspend.service.in \ units/quotaon.service.in \ @@ -2528,7 +2528,7 @@ dist_userunit_DATA += \ endif EXTRA_DIST += \ - units/systemd-bus-pro...@.service.in \ + units/systemd-bus-pro...@.service.m4.in \ units/user/systemd-bus-pro...@.service.in # ------------------------------------------------------------------------------ diff --git a/src/bus-proxyd/bus-proxyd.c b/src/bus-proxyd/bus-proxyd.c index d6607ed..08e2c7c 100644 --- a/src/bus-proxyd/bus-proxyd.c +++ b/src/bus-proxyd/bus-proxyd.c @@ -45,6 +45,7 @@ #include "def.h" #include "capability.h" #include "bus-policy.h" +#include "smack-util.h" static char *arg_address = NULL; static char *arg_command_line_buffer = NULL; @@ -1234,6 +1235,22 @@ int main(int argc, char *argv[]) { if (is_unix) { (void) getpeercred(in_fd, &ucred); (void) getpeersec(in_fd, &peersec); + +#ifdef HAVE_SMACK + if (mac_smack_use()) { + if (peersec) { + + r = mac_smack_apply_pid(getpid(), peersec); + if (r < 0) + log_warning("Failed to set SMACK label %s : %s", peersec, strerror(-r)); + } else + log_warning("Invalid SMACK label"); + + r = drop_capability(CAP_MAC_ADMIN); + if (r < 0) + log_warning("Failed to drop CAP_MAC_ADMIN: %s", strerror(-r)); + } +#endif } if (arg_drop_privileges) { diff --git a/src/shared/capability.c b/src/shared/capability.c index 0226542..9dc42ec 100644 --- a/src/shared/capability.c +++ b/src/shared/capability.c @@ -285,3 +285,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 3e6d999..6f2f6f9 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-pro...@.service.in b/units/systemd-bus-pro...@.service.in deleted file mode 100644 index eef703f..0000000 --- a/units/systemd-bus-pro...@.service.in +++ /dev/null @@ -1,22 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=Legacy D-Bus Protocol Compatibility Daemon - -[Service] -# The first argument will be replaced by the service by information on -# the process requesting the proxy, we need a placeholder to keep the -# space available for this. -ExecStart=@rootlibexecdir@/systemd-bus-proxyd --drop-privileges --address=kernel:path=/dev/kdbus/0-system/bus --configuration=/etc/dbus-1/system.conf --configuration=/etc/dbus-1/system-local.conf --configuration=/etc/dbus-1/system.d/ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx -NotifyAccess=main -CapabilityBoundingSet=CAP_IPC_OWNER CAP_SETUID CAP_SETGID CAP_SETPCAP -PrivateTmp=yes -PrivateDevices=yes -PrivateNetwork=yes -ProtectSystem=full -ProtectHome=yes diff --git a/units/systemd-bus-pro...@.service.m4.in b/units/systemd-bus-pro...@.service.m4.in new file mode 100644 index 0000000..18ff607 --- /dev/null +++ b/units/systemd-bus-pro...@.service.m4.in @@ -0,0 +1,22 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=Legacy D-Bus Protocol Compatibility Daemon + +[Service] +# The first argument will be replaced by the service by information on +# the process requesting the proxy, we need a placeholder to keep the +# space available for this. +ExecStart=@rootlibexecdir@/systemd-bus-proxyd --drop-privileges --address=kernel:path=/dev/kdbus/0-system/bus --configuration=/etc/dbus-1/system.conf --configuration=/etc/dbus-1/system-local.conf --configuration=/etc/dbus-1/system.d/ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx +NotifyAccess=main +CapabilityBoundingSet=CAP_IPC_OWNER CAP_SETUID CAP_SETGID CAP_SETPCAP m4_ifdef(`HAVE_SMACK', CAP_MAC_ADMIN ) +PrivateTmp=yes +PrivateDevices=yes +PrivateNetwork=yes +ProtectSystem=full +ProtectHome=yes diff --git a/units/u...@.service.in b/units/u...@.service.in deleted file mode 100644 index 1e21d51..0000000 --- a/units/u...@.service.in +++ /dev/null @@ -1,19 +0,0 @@ -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=User Manager for UID %i -After=systemd-user-sessions.service - -[Service] -User=%i -PAMName=systemd-user -Type=notify -ExecStart=-@rootlibexecdir@/systemd --user -Slice=user-%i.slice -KillMode=mixed -Delegate=yes diff --git a/units/u...@.service.m4.in b/units/u...@.service.m4.in new file mode 100644 index 0000000..340c02b --- /dev/null +++ b/units/u...@.service.m4.in @@ -0,0 +1,23 @@ +# This file is part of systemd. +# +# systemd is free software; you can redistribute it and/or modify it +# under the terms of the GNU Lesser General Public License as published by +# the Free Software Foundation; either version 2.1 of the License, or +# (at your option) any later version. + +[Unit] +Description=User Manager for UID %i +After=systemd-user-sessions.service + +[Service] +User=%i +PAMName=systemd-user +Type=notify +ExecStart=-@rootlibexecdir@/systemd --user +Slice=user-%i.slice +KillMode=mixed +Delegate=yes +m4_ifdef(`HAVE_SMACK', +Capabilities=cap_mac_admin=i +SecureBits=keep-caps +) -- 2.1.2 _______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel