From 96bb682b6fa33faaff5c3db7506e9864fe5c09dc Mon Sep 17 00:00:00 2001 From: Dan Walsh Date: Thu, 16 Jan 2014 12:59:10 +0100 Subject: [PATCH] Fix SELinux check for transient units. (#1008864) SELinux does not have a path to check for a snapshot servic creation. This ends up giving us a bogus check. On snapshot creation we should check if the remote process type, has the ability to start a service with the type that systemd is running with. --- src/core/dbus-manager.c | 6 +++--- src/core/selinux-access.c | 9 +++++---- src/core/selinux-access.h | 13 +++++++++++++ 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 8f4d017..7be5d13 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1102,7 +1102,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, dbus_bool_t cleanup; Snapshot *s; - SELINUX_ACCESS_CHECK(connection, message, "start"); + SELINUX_RUNTIME_UNIT_ACCESS_CHECK(connection, message, "start"); if (!dbus_message_get_args( message, @@ -1155,7 +1155,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, return bus_send_error_reply(connection, message, &error, -ENOENT); } - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "stop"); + SELINUX_RUNTIME_UNIT_ACCESS_CHECK(connection, message, "stop"); snapshot_remove(SNAPSHOT(u)); reply = dbus_message_new_method_return(message); @@ -1765,7 +1765,7 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection, if (r < 0) return bus_send_error_reply(connection, message, &error, r); - SELINUX_UNIT_ACCESS_CHECK(u, connection, message, "start"); + SELINUX_RUNTIME_UNIT_ACCESS_CHECK(connection, message, "start"); if (u->load_state != UNIT_NOT_FOUND || set_size(u->dependencies[UNIT_REFERENCED_BY]) > 0) { dbus_set_error(&error, BUS_ERROR_UNIT_EXISTS, "Unit %s already exists.", name); diff --git a/src/core/selinux-access.c b/src/core/selinux-access.c index 0a3ee18..5d85b26 100644 --- a/src/core/selinux-access.c +++ b/src/core/selinux-access.c @@ -374,8 +374,9 @@ int selinux_access_check( goto finish; } - if (path) { - tclass = "service"; + + tclass = "service"; + if (path && !strneq(path,"system", strlen("system"))) { /* get the file context of the unit file */ r = getfilecon(path, &fcon); if (r < 0) { @@ -384,9 +385,9 @@ int selinux_access_check( log_error("Failed to get security context on %s: %m",path); goto finish; } - } else { - tclass = "system"; + if (path) + tclass = "system"; r = getcon(&fcon); if (r < 0) { dbus_set_error(error, DBUS_ERROR_ACCESS_DENIED, "Failed to get current context."); diff --git a/src/core/selinux-access.h b/src/core/selinux-access.h index 2d7ac64..92acd69 100644 --- a/src/core/selinux-access.h +++ b/src/core/selinux-access.h @@ -36,6 +36,18 @@ int selinux_access_check(DBusConnection *connection, DBusMessage *message, const DBusConnection *_c = (connection); \ DBusMessage *_m = (message); \ dbus_error_init(&_error); \ + _r = selinux_access_check(_c, _m, "system", (permission), &_error); \ + if (_r < 0) \ + return bus_send_error_reply(_c, _m, &_error, _r); \ + } while (false) + +#define SELINUX_RUNTIME_UNIT_ACCESS_CHECK(connection, message, permission) \ + do { \ + DBusError _error; \ + int _r; \ + DBusConnection *_c = (connection); \ + DBusMessage *_m = (message); \ + dbus_error_init(&_error); \ _r = selinux_access_check(_c, _m, NULL, (permission), &_error); \ if (_r < 0) \ return bus_send_error_reply(_c, _m, &_error, _r); \ @@ -57,6 +69,7 @@ int selinux_access_check(DBusConnection *connection, DBusMessage *message, const #else #define SELINUX_ACCESS_CHECK(connection, message, permission) do { } while (false) +#define SELINUX_RUNTIME_UNIT_ACCESS_CHECK(connection, message, permission) do { } while (false) #define SELINUX_UNIT_ACCESS_CHECK(unit, connection, message, permission) do { } while (false) #endif