summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2011-03-18 03:13:15 +0100
committerLennart Poettering <lennart@poettering.net>2011-03-18 04:52:45 +0100
commit260abb780a135e4cae8c10715c7e85675efc345a (patch)
treea21a20d20b33ea05c68442b9970e0b6d9a02434e /src
parent893844ed434e35e6227e0b17c16b7047360170e2 (diff)
exec: properly apply capability bounding set, add inverted bounding sets
Diffstat (limited to 'src')
-rw-r--r--src/dbus-execute.c18
-rw-r--r--src/dbus-execute.h3
-rw-r--r--src/execute.c15
-rw-r--r--src/load-fragment.c21
4 files changed, 51 insertions, 6 deletions
diff --git a/src/dbus-execute.c b/src/dbus-execute.c
index 504651fc9f..35e6d377ee 100644
--- a/src/dbus-execute.c
+++ b/src/dbus-execute.c
@@ -234,6 +234,24 @@ int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const ch
return 0;
}
+int bus_execute_append_capability_bs(Manager *m, DBusMessageIter *i, const char *property, void *data) {
+ ExecContext *c = data;
+ uint64_t normal, inverted;
+
+ assert(m);
+ assert(i);
+ assert(property);
+ assert(c);
+
+ /* We store this negated internally, to match the kernel, bu
+ * we expose it normalized. */
+
+ normal = *(uint64_t*) data;
+ inverted = ~normal;
+
+ return bus_property_append_uint64(m, i, property, &inverted);
+}
+
int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data) {
ExecContext *c = data;
char *t = NULL;
diff --git a/src/dbus-execute.h b/src/dbus-execute.h
index 082456a9ec..8bfaaaf120 100644
--- a/src/dbus-execute.h
+++ b/src/dbus-execute.h
@@ -131,7 +131,7 @@
{ interface, "SyslogLevelPrefix", bus_property_append_bool, "b", &(context).syslog_level_prefix }, \
{ interface, "Capabilities", bus_execute_append_capabilities, "s",&(context) }, \
{ interface, "SecureBits", bus_property_append_int, "i", &(context).secure_bits }, \
- { interface, "CapabilityBoundingSetDrop", bus_property_append_uint64, "t", &(context).capability_bounding_set_drop }, \
+ { interface, "CapabilityBoundingSet", bus_execute_append_capability_bs, "t", &(context).capability_bounding_set_drop }, \
{ interface, "User", bus_property_append_string, "s", (context).user }, \
{ interface, "Group", bus_property_append_string, "s", (context).group }, \
{ interface, "SupplementaryGroups", bus_property_append_strv, "as", (context).supplementary_groups }, \
@@ -167,6 +167,7 @@ int bus_execute_append_cpu_sched_priority(Manager *m, DBusMessageIter *i, const
int bus_execute_append_affinity(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_timer_slack_nsec(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_capabilities(Manager *m, DBusMessageIter *i, const char *property, void *data);
+int bus_execute_append_capability_bs(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_rlimits(Manager *m, DBusMessageIter *i, const char *property, void *data);
int bus_execute_append_command(Manager *m, DBusMessageIter *u, const char *property, void *data);
int bus_execute_append_kill_mode(Manager *m, DBusMessageIter *i, const char *property, void *data);
diff --git a/src/execute.c b/src/execute.c
index c1edf61fb1..a467411f7d 100644
--- a/src/execute.c
+++ b/src/execute.c
@@ -1249,6 +1249,15 @@ int exec_spawn(ExecCommand *command,
}
}
+ if (context->capability_bounding_set_drop)
+ for (i = 0; i <= CAP_LAST_CAP; i++)
+ if (context->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) i)) {
+ if (prctl(PR_CAPBSET_DROP, i) < 0) {
+ r = EXIT_CAPABILITIES;
+ goto fail_child;
+ }
+ }
+
if (context->user)
if (enforce_user(context, uid) < 0) {
r = EXIT_USER;
@@ -1664,15 +1673,15 @@ void exec_context_dump(ExecContext *c, FILE* f, const char *prefix) {
(c->secure_bits & SECURE_NOROOT_LOCKED) ? "noroot-locked" : "");
if (c->capability_bounding_set_drop) {
- fprintf(f, "%sCapabilityBoundingSetDrop:", prefix);
+ fprintf(f, "%sCapabilityBoundingSet:", prefix);
for (i = 0; i <= CAP_LAST_CAP; i++)
- if (c->capability_bounding_set_drop & (1 << i)) {
+ if (!(c->capability_bounding_set_drop & ((uint64_t) 1ULL << (uint64_t) i))) {
char *t;
if ((t = cap_to_name(i))) {
fprintf(f, " %s", t);
- free(t);
+ cap_free(t);
}
}
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 334bc713be..ac22b94509 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -852,12 +852,24 @@ static int config_parse_bounding_set(
char *w;
size_t l;
char *state;
+ bool invert = false;
+ uint64_t sum = 0;
assert(filename);
assert(lvalue);
assert(rvalue);
assert(data);
+ if (rvalue[0] == '~') {
+ invert = true;
+ rvalue++;
+ }
+
+ /* Note that we store this inverted internally, since the
+ * kernel wants it like this. But we actually expose it
+ * non-inverted everywhere to have a fully normalized
+ * interface. */
+
FOREACH_WORD_QUOTED(w, l, rvalue, state) {
char *t;
int r;
@@ -874,9 +886,14 @@ static int config_parse_bounding_set(
return 0;
}
- c->capability_bounding_set_drop |= 1 << cap;
+ sum |= ((uint64_t) 1ULL) << (uint64_t) cap;
}
+ if (invert)
+ c->capability_bounding_set_drop |= sum;
+ else
+ c->capability_bounding_set_drop |= ~sum;
+
return 0;
}
@@ -1772,7 +1789,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "SyslogLevelPrefix", config_parse_bool, &(context).syslog_level_prefix, section }, \
{ "Capabilities", config_parse_capabilities, &(context), section }, \
{ "SecureBits", config_parse_secure_bits, &(context), section }, \
- { "CapabilityBoundingSetDrop", config_parse_bounding_set, &(context), section }, \
+ { "CapabilityBoundingSet", config_parse_bounding_set, &(context), section }, \
{ "TimerSlackNSec", config_parse_timer_slack_nsec,&(context), section }, \
{ "LimitCPU", config_parse_limit, &(context).rlimit[RLIMIT_CPU], section }, \
{ "LimitFSIZE", config_parse_limit, &(context).rlimit[RLIMIT_FSIZE], section }, \