summaryrefslogtreecommitdiffstats
path: root/src/nspawn
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2019-03-22 21:06:17 +0100
committerGitHub <noreply@github.com>2019-03-22 21:06:17 +0100
commit83276695c67e4be2ccbce696d3e6c7dbd6825473 (patch)
treeac793974966be389810c49bda0a7739e3aa5255e /src/nspawn
parentMerge pull request #12075 from keszybz/two-docs (diff)
parentnspawn-oci: fix double free (diff)
downloadsystemd-83276695c67e4be2ccbce696d3e6c7dbd6825473.tar.xz
systemd-83276695c67e4be2ccbce696d3e6c7dbd6825473.zip
Merge pull request #12079 from keszybz/fuzz-nspawn-oci
Add fuzzer for nspawn-oci
Diffstat (limited to 'src/nspawn')
-rw-r--r--src/nspawn/nspawn-oci.c81
-rw-r--r--src/nspawn/nspawn-settings.c5
-rw-r--r--src/nspawn/nspawn-settings.h2
-rw-r--r--src/nspawn/nspawn.c4
4 files changed, 36 insertions, 56 deletions
diff --git a/src/nspawn/nspawn-oci.c b/src/nspawn/nspawn-oci.c
index dd191aaa29..6c35c926ab 100644
--- a/src/nspawn/nspawn-oci.c
+++ b/src/nspawn/nspawn-oci.c
@@ -517,6 +517,20 @@ static bool oci_exclude_mount(const char *path) {
return false;
}
+typedef struct oci_mount_data {
+ char *destination;
+ char *source;
+ char *type;
+ char **options;
+} oci_mount_data;
+
+static void cleanup_oci_mount_data(oci_mount_data *data) {
+ free(data->destination);
+ free(data->source);
+ strv_free(data->options);
+ free(data->type);
+}
+
static int oci_mounts(const char *name, JsonVariant *v, JsonDispatchFlags flags, void *userdata) {
Settings *s = userdata;
JsonVariant *e;
@@ -525,56 +539,42 @@ static int oci_mounts(const char *name, JsonVariant *v, JsonDispatchFlags flags,
assert(s);
JSON_VARIANT_ARRAY_FOREACH(e, v) {
-
- struct mount_data {
- char *destination;
- char *source;
- char *type;
- char **options;
- } data = {};
-
static const JsonDispatch table[] = {
- { "destination", JSON_VARIANT_STRING, oci_absolute_path, offsetof(struct mount_data, destination), JSON_MANDATORY },
- { "source", JSON_VARIANT_STRING, json_dispatch_string, offsetof(struct mount_data, source), 0 },
- { "options", JSON_VARIANT_ARRAY, json_dispatch_strv, offsetof(struct mount_data, options), 0, },
- { "type", JSON_VARIANT_STRING, json_dispatch_string, offsetof(struct mount_data, type), 0 },
+ { "destination", JSON_VARIANT_STRING, oci_absolute_path, offsetof(oci_mount_data, destination), JSON_MANDATORY },
+ { "source", JSON_VARIANT_STRING, json_dispatch_string, offsetof(oci_mount_data, source), 0 },
+ { "options", JSON_VARIANT_ARRAY, json_dispatch_strv, offsetof(oci_mount_data, options), 0, },
+ { "type", JSON_VARIANT_STRING, json_dispatch_string, offsetof(oci_mount_data, type), 0 },
{}
};
_cleanup_free_ char *joined_options = NULL;
CustomMount *m;
+ _cleanup_(cleanup_oci_mount_data) oci_mount_data data = {};
r = json_dispatch(e, table, oci_unexpected, flags, &data);
if (r < 0)
- goto fail_item;
+ return r;
- if (!path_is_absolute(data.destination)) {
- r = json_log(e, flags, SYNTHETIC_ERRNO(EINVAL),
- "Mount destination not an absolute path: %s", data.destination);
- goto fail_item;
- }
+ if (!path_is_absolute(data.destination))
+ return json_log(e, flags, SYNTHETIC_ERRNO(EINVAL),
+ "Mount destination not an absolute path: %s", data.destination);
if (oci_exclude_mount(data.destination))
- goto skip_item;
+ continue;
if (data.options) {
joined_options = strv_join(data.options, ",");
- if (!joined_options) {
- r = log_oom();
- goto fail_item;
- }
+ if (!joined_options)
+ return log_oom();
}
if (!data.type || streq(data.type, "bind")) {
-
- if (!path_is_absolute(data.source)) {
+ if (data.source && !path_is_absolute(data.source)) {
char *joined;
joined = path_join(s->bundle, data.source);
- if (!joined) {
- r = log_oom();
- goto fail_item;
- }
+ if (!joined)
+ return log_oom();
free_and_replace(data.source, joined);
}
@@ -584,32 +584,13 @@ static int oci_mounts(const char *name, JsonVariant *v, JsonDispatchFlags flags,
m = custom_mount_add(&s->custom_mounts, &s->n_custom_mounts, CUSTOM_MOUNT_BIND);
} else
m = custom_mount_add(&s->custom_mounts, &s->n_custom_mounts, CUSTOM_MOUNT_ARBITRARY);
- if (!m) {
- r = log_oom();
- goto fail_item;
- }
+ if (!m)
+ return log_oom();
m->destination = TAKE_PTR(data.destination);
m->source = TAKE_PTR(data.source);
m->options = TAKE_PTR(joined_options);
m->type_argument = TAKE_PTR(data.type);
-
- strv_free(data.options);
- continue;
-
- fail_item:
- free(data.destination);
- free(data.source);
- strv_free(data.options);
- free(data.type);
-
- return r;
-
- skip_item:
- free(data.destination);
- free(data.source);
- strv_free(data.options);
- free(data.type);
}
return 0;
diff --git a/src/nspawn/nspawn-settings.c b/src/nspawn/nspawn-settings.c
index ab69f24c54..476cb0779e 100644
--- a/src/nspawn/nspawn-settings.c
+++ b/src/nspawn/nspawn-settings.c
@@ -110,7 +110,7 @@ static void free_oci_hooks(OciHook *h, size_t n) {
free(h);
}
-void device_node_free_many(DeviceNode *node, size_t n) {
+void device_node_array_free(DeviceNode *node, size_t n) {
size_t i;
for (i = 0; i < n; i++)
@@ -156,8 +156,7 @@ Settings* settings_free(Settings *s) {
sd_bus_message_unref(s->properties);
free(s->supplementary_gids);
- device_node_free_many(s->extra_nodes, s->n_extra_nodes);
- free(s->extra_nodes);
+ device_node_array_free(s->extra_nodes, s->n_extra_nodes);
free(s->network_namespace_path);
strv_free(s->sysctl);
diff --git a/src/nspawn/nspawn-settings.h b/src/nspawn/nspawn-settings.h
index cc802f77af..231082706d 100644
--- a/src/nspawn/nspawn-settings.h
+++ b/src/nspawn/nspawn-settings.h
@@ -254,4 +254,4 @@ TimezoneMode timezone_mode_from_string(const char *s) _pure_;
int parse_link_journal(const char *s, LinkJournal *ret_mode, bool *ret_try);
-void device_node_free_many(DeviceNode *node, size_t n);
+void device_node_array_free(DeviceNode *node, size_t n);
diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c
index ee930972ad..5ff02130d6 100644
--- a/src/nspawn/nspawn.c
+++ b/src/nspawn/nspawn.c
@@ -3958,7 +3958,7 @@ static int merge_settings(Settings *settings, const char *path) {
arg_console_width = settings->console_width;
arg_console_height = settings->console_height;
- device_node_free_many(arg_extra_nodes, arg_n_extra_nodes);
+ device_node_array_free(arg_extra_nodes, arg_n_extra_nodes);
arg_extra_nodes = TAKE_PTR(settings->extra_nodes);
arg_n_extra_nodes = settings->n_extra_nodes;
@@ -5066,7 +5066,7 @@ finish:
custom_mount_free_all(arg_custom_mounts, arg_n_custom_mounts);
expose_port_free_all(arg_expose_ports);
rlimit_free_all(arg_rlimit);
- device_node_free_many(arg_extra_nodes, arg_n_extra_nodes);
+ device_node_array_free(arg_extra_nodes, arg_n_extra_nodes);
if (r < 0)
return r;