diff options
author | Lennart Poettering <lennart@poettering.net> | 2019-03-22 21:06:17 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-03-22 21:06:17 +0100 |
commit | 83276695c67e4be2ccbce696d3e6c7dbd6825473 (patch) | |
tree | ac793974966be389810c49bda0a7739e3aa5255e /src/nspawn | |
parent | Merge pull request #12075 from keszybz/two-docs (diff) | |
parent | nspawn-oci: fix double free (diff) | |
download | systemd-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.c | 81 | ||||
-rw-r--r-- | src/nspawn/nspawn-settings.c | 5 | ||||
-rw-r--r-- | src/nspawn/nspawn-settings.h | 2 | ||||
-rw-r--r-- | src/nspawn/nspawn.c | 4 |
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; |