diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml
index f5d42350dd..afa7a17d2d 100644
--- a/man/systemd-nspawn.xml
+++ b/man/systemd-nspawn.xml
@@ -754,7 +754,7 @@
container, with the exception of the loopback device and those
specified with and
configured with . If this
- option is specified, the CAP_NET_ADMIN capability will be
+ option is specified, the CAP_NET_ADMIN capability will be
added to the set of capabilities the container retains. The
latter may be disabled by using .
If this option is not specified (or implied by one of the options
@@ -943,17 +943,27 @@
- List one or more additional capabilities to grant the container.
- Takes a comma-separated list of capability names, see
- capabilities7
+ List one or more additional capabilities to grant the container. Takes a
+ comma-separated list of capability names, see capabilities7
for more information. Note that the following capabilities will be granted in any way:
- CAP_AUDIT_CONTROL, CAP_AUDIT_WRITE, CAP_CHOWN, CAP_DAC_OVERRIDE, CAP_DAC_READ_SEARCH,
- CAP_FOWNER, CAP_FSETID, CAP_IPC_OWNER, CAP_KILL, CAP_LEASE, CAP_LINUX_IMMUTABLE,
- CAP_MKNOD, CAP_NET_BIND_SERVICE, CAP_NET_BROADCAST, CAP_NET_RAW, CAP_SETFCAP,
- CAP_SETGID, CAP_SETPCAP, CAP_SETUID, CAP_SYS_ADMIN, CAP_SYS_BOOT, CAP_SYS_CHROOT,
- CAP_SYS_NICE, CAP_SYS_PTRACE, CAP_SYS_RESOURCE, CAP_SYS_TTY_CONFIG. Also CAP_NET_ADMIN
- is retained if is specified. If the special value
- all is passed, all capabilities are retained.
+ CAP_AUDIT_CONTROL, CAP_AUDIT_WRITE,
+ CAP_CHOWN, CAP_DAC_OVERRIDE,
+ CAP_DAC_READ_SEARCH, CAP_FOWNER,
+ CAP_FSETID, CAP_IPC_OWNER, CAP_KILL,
+ CAP_LEASE, CAP_LINUX_IMMUTABLE,
+ CAP_MKNOD, CAP_NET_BIND_SERVICE,
+ CAP_NET_BROADCAST, CAP_NET_RAW,
+ CAP_SETFCAP, CAP_SETGID, CAP_SETPCAP,
+ CAP_SETUID, CAP_SYS_ADMIN,
+ CAP_SYS_BOOT, CAP_SYS_CHROOT,
+ CAP_SYS_NICE, CAP_SYS_PTRACE,
+ CAP_SYS_RESOURCE, CAP_SYS_TTY_CONFIG. Also
+ CAP_NET_ADMIN is retained if is specified.
+ If the special value all is passed, all capabilities are retained.
+
+ If the special value of help is passed, the program will print known
+ capability names and exit.
@@ -962,7 +972,10 @@
Specify one or more additional capabilities to
drop for the container. This allows running the container with
fewer capabilities than the default (see
- above).
+ above).
+
+ If the special value of help is passed, the program will print known
+ capability names and exit.
diff --git a/src/machine/machine.c b/src/machine/machine.c
index acd57aedc4..efe327f381 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -330,36 +330,107 @@ int machine_load(Machine *m) {
return r;
}
-static int machine_start_scope(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
+static int machine_start_scope(
+ Machine *machine,
+ sd_bus_message *more_properties,
+ sd_bus_error *error) {
+
+ _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
+ _cleanup_free_ char *escaped = NULL, *unit = NULL;
+ const char *description;
+ int r;
+
+ assert(machine);
+ assert(machine->leader > 0);
+ assert(!machine->unit);
+
+ escaped = unit_name_escape(machine->name);
+ if (!escaped)
+ return log_oom();
+
+ unit = strjoin("machine-", escaped, ".scope");
+ if (!unit)
+ return log_oom();
+
+ r = sd_bus_message_new_method_call(
+ machine->manager->bus,
+ &m,
+ "org.freedesktop.systemd1",
+ "/org/freedesktop/systemd1",
+ "org.freedesktop.systemd1.Manager",
+ "StartTransientUnit");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(m, "ss", unit, "fail");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_open_container(m, 'a', "(sv)");
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(m, "(sv)", "Slice", "s", SPECIAL_MACHINE_SLICE);
+ if (r < 0)
+ return r;
+
+ description = strjoina(machine->class == MACHINE_VM ? "Virtual Machine " : "Container ", machine->name);
+ r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
+ "PIDs", "au", 1, machine->leader,
+ "Delegate", "b", 1,
+ "CollectMode", "s", "inactive-or-failed",
+ "AddRef", "b", 1,
+ "TasksMax", "t", UINT64_C(16384));
+ if (r < 0)
+ return r;
+
+ if (more_properties) {
+ r = sd_bus_message_copy(m, more_properties, true);
+ if (r < 0)
+ return r;
+ }
+
+ r = sd_bus_message_close_container(m);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_message_append(m, "a(sa(sv))", 0);
+ if (r < 0)
+ return r;
+
+ r = sd_bus_call(NULL, m, 0, error, &reply);
+ if (r < 0)
+ return r;
+
+ machine->unit = TAKE_PTR(unit);
+ machine->referenced = true;
+
+ const char *job;
+ r = sd_bus_message_read(reply, "o", &job);
+ if (r < 0)
+ return r;
+
+ return free_and_strdup(&machine->scope_job, job);
+}
+
+static int machine_ensure_scope(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
+ int r;
+
assert(m);
assert(m->class != MACHINE_HOST);
if (!m->unit) {
- _cleanup_free_ char *escaped = NULL, *scope = NULL;
- char *description, *job = NULL;
- int r;
-
- escaped = unit_name_escape(m->name);
- if (!escaped)
- return log_oom();
-
- scope = strjoin("machine-", escaped, ".scope");
- if (!scope)
- return log_oom();
-
- description = strjoina(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name);
-
- r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, properties, error, &job);
+ r = machine_start_scope(m, properties, error);
if (r < 0)
return log_error_errno(r, "Failed to start machine scope: %s", bus_error_message(error, r));
-
- m->unit = TAKE_PTR(scope);
- m->referenced = true;
- free_and_replace(m->scope_job, job);
}
- if (m->unit)
- hashmap_put(m->manager->machine_units, m->unit, m);
+ assert(m->unit);
+ hashmap_put(m->manager->machine_units, m->unit, m);
return 0;
}
@@ -380,7 +451,7 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
return r;
/* Create cgroup */
- r = machine_start_scope(m, properties, error);
+ r = machine_ensure_scope(m, properties, error);
if (r < 0)
return r;
@@ -404,49 +475,31 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
return 0;
}
-static int machine_stop_scope(Machine *m) {
- _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
- char *job = NULL;
- int r, q;
-
- assert(m);
- assert(m->class != MACHINE_HOST);
-
- if (!m->unit)
- return 0;
-
- r = manager_stop_unit(m->manager, m->unit, &error, &job);
- if (r < 0) {
- log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r));
- sd_bus_error_free(&error);
- } else
- free_and_replace(m->scope_job, job);
-
- if (m->referenced) {
- q = manager_unref_unit(m->manager, m->unit, &error);
- if (q < 0)
- log_warning_errno(q, "Failed to drop reference to machine scope, ignoring: %s", bus_error_message(&error, r));
- m->referenced = false;
- }
-
- return r;
-}
-
int machine_stop(Machine *m) {
int r;
+
assert(m);
if (!IN_SET(m->class, MACHINE_CONTAINER, MACHINE_VM))
return -EOPNOTSUPP;
- r = machine_stop_scope(m);
+ if (m->unit) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ char *job = NULL;
+
+ r = manager_stop_unit(m->manager, m->unit, &error, &job);
+ if (r < 0)
+ return log_error_errno(r, "Failed to stop machine scope: %s", bus_error_message(&error, r));
+
+ free_and_replace(m->scope_job, job);
+ }
m->stopping = true;
machine_save(m);
(void) manager_enqueue_nscd_cache_flush(m->manager);
- return r;
+ return 0;
}
int machine_finalize(Machine *m) {
@@ -583,6 +636,18 @@ void machine_release_unit(Machine *m) {
if (!m->unit)
return;
+ if (m->referenced) {
+ _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+ int r;
+
+ r = manager_unref_unit(m->manager, m->unit, &error);
+ if (r < 0)
+ log_warning_errno(r, "Failed to drop reference to machine scope, ignoring: %s",
+ bus_error_message(&error, r));
+
+ m->referenced = false;
+ }
+
(void) hashmap_remove(m->manager->machine_units, m->unit);
m->unit = mfree(m->unit);
}
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 35e06f5d6a..6fc3b93057 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -1294,98 +1294,6 @@ int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error
return 0;
}
-int manager_start_scope(
- Manager *manager,
- const char *scope,
- pid_t pid,
- const char *slice,
- const char *description,
- sd_bus_message *more_properties,
- sd_bus_error *error,
- char **job) {
-
- _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL;
- int r;
-
- assert(manager);
- assert(scope);
- assert(pid > 1);
-
- r = sd_bus_message_new_method_call(
- manager->bus,
- &m,
- "org.freedesktop.systemd1",
- "/org/freedesktop/systemd1",
- "org.freedesktop.systemd1.Manager",
- "StartTransientUnit");
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "ss", strempty(scope), "fail");
- if (r < 0)
- return r;
-
- r = sd_bus_message_open_container(m, 'a', "(sv)");
- if (r < 0)
- return r;
-
- if (!isempty(slice)) {
- r = sd_bus_message_append(m, "(sv)", "Slice", "s", slice);
- if (r < 0)
- return r;
- }
-
- if (!isempty(description)) {
- r = sd_bus_message_append(m, "(sv)", "Description", "s", description);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_append(m, "(sv)(sv)(sv)(sv)(sv)",
- "PIDs", "au", 1, pid,
- "Delegate", "b", 1,
- "CollectMode", "s", "inactive-or-failed",
- "AddRef", "b", 1,
- "TasksMax", "t", UINT64_C(16384));
- if (r < 0)
- return r;
-
- if (more_properties) {
- r = sd_bus_message_copy(m, more_properties, true);
- if (r < 0)
- return r;
- }
-
- r = sd_bus_message_close_container(m);
- if (r < 0)
- return r;
-
- r = sd_bus_message_append(m, "a(sa(sv))", 0);
- if (r < 0)
- return r;
-
- r = sd_bus_call(manager->bus, m, 0, error, &reply);
- if (r < 0)
- return r;
-
- if (job) {
- const char *j;
- char *copy;
-
- r = sd_bus_message_read(reply, "o", &j);
- if (r < 0)
- return r;
-
- copy = strdup(j);
- if (!copy)
- return -ENOMEM;
-
- *job = copy;
- }
-
- return 1;
-}
-
int manager_unref_unit(
Manager *m,
const char *unit,
diff --git a/src/machine/machined.h b/src/machine/machined.h
index 2298a652c4..205d90f83d 100644
--- a/src/machine/machined.h
+++ b/src/machine/machined.h
@@ -49,7 +49,6 @@ int match_unit_removed(sd_bus_message *message, void *userdata, sd_bus_error *er
int match_properties_changed(sd_bus_message *message, void *userdata, sd_bus_error *error);
int match_job_removed(sd_bus_message *message, void *userdata, sd_bus_error *error);
-int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, sd_bus_message *more_properties, sd_bus_error *error, char **job);
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error);
int manager_unref_unit(Manager *m, const char *unit, sd_bus_error *error);
diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c
index 0b39cda9ba..f94f131f22 100644
--- a/src/nspawn/nspawn-seccomp.c
+++ b/src/nspawn/nspawn-seccomp.c
@@ -139,11 +139,10 @@ static int seccomp_add_default_syscall_filter(
*/
};
- int r;
- size_t i;
char **p;
+ int r;
- for (i = 0; i < ELEMENTSOF(whitelist); i++) {
+ for (size_t i = 0; i < ELEMENTSOF(whitelist); i++) {
if (whitelist[i].capability != 0 && (cap_list_retain & (1ULL << whitelist[i].capability)) == 0)
continue;
@@ -153,7 +152,7 @@ static int seccomp_add_default_syscall_filter(
}
STRV_FOREACH(p, syscall_whitelist) {
- r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, false);
+ r = seccomp_add_syscall_filter_item(ctx, *p, SCMP_ACT_ALLOW, syscall_blacklist, true);
if (r < 0)
log_warning_errno(r, "Failed to add rule for system call %s on %s, ignoring: %m",
*p, seccomp_arch_to_string(arch));
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index 6286a28f1d..7f44272a88 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -492,6 +492,46 @@ static int detect_unified_cgroup_hierarchy_from_image(const char *directory) {
return 0;
}
+static int parse_capability_spec(const char *spec, uint64_t *ret_mask) {
+ uint64_t mask = 0;
+ int r;
+
+ for (;;) {
+ _cleanup_free_ char *t = NULL;
+
+ r = extract_first_word(&spec, &t, ",", 0);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse capability %s.", t);
+ if (r == 0)
+ break;
+
+ if (streq(t, "help")) {
+ for (int i = 0; i < capability_list_length(); i++) {
+ const char *name;
+
+ name = capability_to_name(i);
+ if (name)
+ puts(name);
+ }
+
+ return 0; /* quit */
+ }
+
+ if (streq(t, "all"))
+ mask = (uint64_t) -1;
+ else {
+ r = capability_from_name(t);
+ if (r < 0)
+ return log_error_errno(r, "Failed to parse capability %s.", t);
+
+ mask |= 1ULL << r;
+ }
+ }
+
+ *ret_mask = mask;
+ return 1; /* continue */
+}
+
static int parse_share_ns_env(const char *name, unsigned long ns_flag) {
int r;
@@ -695,7 +735,6 @@ static int parse_argv(int argc, char *argv[]) {
};
int c, r;
- const char *p;
uint64_t plus = 0, minus = 0;
bool mask_all_settings = false, mask_no_settings = false;
@@ -937,37 +976,18 @@ static int parse_argv(int argc, char *argv[]) {
case ARG_CAPABILITY:
case ARG_DROP_CAPABILITY: {
- p = optarg;
- for (;;) {
- _cleanup_free_ char *t = NULL;
-
- r = extract_first_word(&p, &t, ",", 0);
- if (r < 0)
- return log_error_errno(r, "Failed to parse capability %s.", t);
- if (r == 0)
- break;
-
- if (streq(t, "all")) {
- if (c == ARG_CAPABILITY)
- plus = (uint64_t) -1;
- else
- minus = (uint64_t) -1;
- } else {
- r = capability_from_name(t);
- if (r < 0)
- return log_error_errno(r, "Failed to parse capability %s.", t);
-
- if (c == ARG_CAPABILITY)
- plus |= 1ULL << r;
- else
- minus |= 1ULL << r;
- }
- }
+ uint64_t m;
+ r = parse_capability_spec(optarg, &m);
+ if (r <= 0)
+ return r;
+ if (c == ARG_CAPABILITY)
+ plus |= m;
+ else
+ minus |= m;
arg_settings_mask |= SETTING_CAPABILITY;
break;
}
-
case ARG_NO_NEW_PRIVILEGES:
r = parse_boolean(optarg);
if (r < 0)
diff --git a/src/resolve/resolved-dnstls-gnutls.c b/src/resolve/resolved-dnstls-gnutls.c
index 9e5e60fcce..ed0a31e8bf 100644
--- a/src/resolve/resolved-dnstls-gnutls.c
+++ b/src/resolve/resolved-dnstls-gnutls.c
@@ -9,7 +9,7 @@
#include "resolved-dns-stream.h"
#include "resolved-dnstls.h"
-#define PRIORTY_STRING "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2"
+#define TLS_PROTOCOL_PRIORITY "NORMAL:-VERS-ALL:+VERS-TLS1.3:+VERS-TLS1.2"
DEFINE_TRIVIAL_CLEANUP_FUNC(gnutls_session_t, gnutls_deinit);
static ssize_t dnstls_stream_writev(gnutls_transport_ptr_t p, const giovec_t *iov, int iovcnt) {
@@ -38,7 +38,7 @@ int dnstls_stream_connect_tls(DnsStream *stream, DnsServer *server) {
return r;
/* As DNS-over-TLS is a recent protocol, older TLS versions can be disabled */
- r = gnutls_priority_set_direct(gs, PRIORTY_STRING, NULL);
+ r = gnutls_priority_set_direct(gs, TLS_PROTOCOL_PRIORITY, NULL);
if (r < 0)
return r;