From 9ddd62cda1cda0df88060c236da7652873553419 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Thu, 21 Mar 2019 23:16:56 +0100 Subject: [PATCH 1/5] fuzz-nspawn-oci: add fuzzer for the oci bundle loader --- src/fuzz/fuzz-nspawn-oci.c | 28 ++++++ src/fuzz/meson.build | 5 + test/fuzz/fuzz-nspawn-oci/basic.json | 141 +++++++++++++++++++++++++++ 3 files changed, 174 insertions(+) create mode 100644 src/fuzz/fuzz-nspawn-oci.c create mode 100644 test/fuzz/fuzz-nspawn-oci/basic.json diff --git a/src/fuzz/fuzz-nspawn-oci.c b/src/fuzz/fuzz-nspawn-oci.c new file mode 100644 index 0000000000..f7b59f13ba --- /dev/null +++ b/src/fuzz/fuzz-nspawn-oci.c @@ -0,0 +1,28 @@ +/* SPDX-License-Identifier: LGPL-2.1+ */ + +#include + +#include "alloc-util.h" +#include "fd-util.h" +#include "fuzz.h" +#include "nspawn-oci.h" + +int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { + _cleanup_fclose_ FILE *f = NULL; + _cleanup_(settings_freep) Settings *s = NULL; + + if (size == 0) + return 0; + + f = fmemopen((char*) data, size, "re"); + assert_se(f); + + /* We don't want to fill the logs with messages about parse errors. + * Disable most logging if not running standalone */ + if (!getenv("SYSTEMD_LOG_LEVEL")) + log_set_max_level(LOG_CRIT); + + (void) oci_load(f, "/dev/null", &s); + + return 0; +} diff --git a/src/fuzz/meson.build b/src/fuzz/meson.build index 241fe02edb..0d1ad2b1e1 100644 --- a/src/fuzz/meson.build +++ b/src/fuzz/meson.build @@ -130,6 +130,11 @@ fuzzers += [ libnspawn_core], []], + [['src/fuzz/fuzz-nspawn-oci.c'], + [libshared, + libnspawn_core], + []], + [['src/fuzz/fuzz-calendarspec.c'], [libshared], []], diff --git a/test/fuzz/fuzz-nspawn-oci/basic.json b/test/fuzz/fuzz-nspawn-oci/basic.json new file mode 100644 index 0000000000..f42739e03a --- /dev/null +++ b/test/fuzz/fuzz-nspawn-oci/basic.json @@ -0,0 +1,141 @@ +{ + "ociVersion": "1.0.0", + + "root": { + "path": "rootfs", + "readonly": true + }, + + "process": { + "terminal": false, + "consoleSize": { + "height":6667, + "width":6668 + }, + + "user": { + "uid": 14, + "gid": 14, + "additionalGids": [59, 81] + }, + + "args": [ + "/tmp/verify.sh" + ], + + "env": [ + "FOO=BAR", + "WITHSPACES=FOO BAR", + "WITHSHELLCHARS=$ASDF \\\"asdf asdf\\\" !", + "WITHCONTROLCHARS=\\123\\125\\010\\020", + "TERM=xterm" + ], + + "cwd": "/tmp/src", + + "rlimits": [ + { + "type": "RLIMIT_NOFILE", + "hard": 1020, + "soft": 1020 + } + ] + }, + + "mounts": [ + { + "destination": "/tmp/src", + "source": "src", + "options": ["ro"] + }, + + { + "destination": "/tmp/verify.sh", + "source": "verify.sh", + "options": ["ro"] + }, + + { + "destination": "/proc", + "type": "proc", + "source": "proc" + }, + { + "destination": "/dev", + "type": "tmpfs", + "source": "tmpfs", + "options": [ + "mode=777" + ] + }, + { + "destination": "/dev/pts", + "type": "devpts", + "source": "devpts", + "options": [ + "mode=777" + ] + }, + { + "destination": "/dev/shm", + "type": "tmpfs", + "source": "shm", + "options": [ + "mode=777" + ] + }, + { + "destination": "/dev/mqueue", + "type": "mqueue", + "source": "mqueue", + "options": [ + "mode=777" + ] + }, + { + "destination": "/sys", + "type": "sysfs", + "source": "sysfs", + "options": [ + "mode=777" + ] + }, + { + "destination": "/sys/fs/cgroup", + "type": "cgroup", + "source": "cgroup", + "options": [ + "mode=777" + ] + } + ], + + "hooks": {}, + + "linux": { + "resources": { + "devices": [ + { + "allow": false, + "access": "rwm" + } + ] + }, + "namespaces": [ + { + "type": "pid" + }, + { + "type": "ipc" + }, + { + "type": "mount" + } + ] + }, + + "annotations": { + "com.example.key1": "value1", + "com.example.key2": "value2" + } +} From b2e07b1a022f1e62f54be138b4757620cddafc73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Mar 2019 11:51:21 +0100 Subject: [PATCH 2/5] nspawn-oci: use _cleanup_ in one more place --- src/nspawn/nspawn-oci.c | 79 ++++++++++++++++------------------------- 1 file changed, 30 insertions(+), 49 deletions(-) diff --git a/src/nspawn/nspawn-oci.c b/src/nspawn/nspawn-oci.c index dd191aaa29..561990f9e0 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)) { 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; From b1f13b0e75a27db2843bc170322d3dfc49184c04 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Mar 2019 12:04:32 +0100 Subject: [PATCH 3/5] nspawn-oci: mount source is optional --- src/nspawn/nspawn-oci.c | 2 +- ...h-db0595479ee2e625fa5419a821009b5eb4d809b7 | 92 +++++++++++++++++++ 2 files changed, 93 insertions(+), 1 deletion(-) create mode 100644 test/fuzz/fuzz-nspawn-oci/crash-db0595479ee2e625fa5419a821009b5eb4d809b7 diff --git a/src/nspawn/nspawn-oci.c b/src/nspawn/nspawn-oci.c index 561990f9e0..6c35c926ab 100644 --- a/src/nspawn/nspawn-oci.c +++ b/src/nspawn/nspawn-oci.c @@ -569,7 +569,7 @@ static int oci_mounts(const char *name, JsonVariant *v, JsonDispatchFlags flags, } 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); diff --git a/test/fuzz/fuzz-nspawn-oci/crash-db0595479ee2e625fa5419a821009b5eb4d809b7 b/test/fuzz/fuzz-nspawn-oci/crash-db0595479ee2e625fa5419a821009b5eb4d809b7 new file mode 100644 index 0000000000..0bf017ce6e --- /dev/null +++ b/test/fuzz/fuzz-nspawn-oci/crash-db0595479ee2e625fa5419a821009b5eb4d809b7 @@ -0,0 +1,92 @@ +{ + "ociVersion": "1.0.0", + + "root": { + "path": "rootfs", + "readonly": true + }, + + "process": { + "terminal": false, + "consoleSize": { + "height":6667, + "width":6668 + }, + + "user": { + "uid": 14, + "gid": 14, + "additionalGids": [59, 81] + }, + + "args": [ + "/tmp/verify.sh" + ], + + "env": [ + "FOO=BAR", + "WITHSPACES=FOO BAR", + "WITHSHELLCHARS=$ASDF \\\"asdf asdf\\\" !", + "WITHCONTROLCHARS=\\123\\125\\010\\020", + "TERM=xterm" + ], + + "cwd": "/tmp/src", + + "rlimits": [ + { + "type": "RLIMIT_NOFILE", + "hard": 1020, + "soft": 1020 + } + ] + }, + + "mounts": [ + { + "destination": "/tmp/src" }, + { + "source": "sysfs", + "options": [ + "mode=777" + ] + }, + { + "destination": "/sys/fs/cgroup", + "type": "cgroup", + "source": "cgroup", + "options": [ + "mode=777" + ] + } + ], + + "hooks": {}, + + "linux": { + "resources": { + "devices": [ + { + "allow": false, + "access": "rwm" + } + ] + }, + "namespaces": [ + { + "type": "pid" + }, + { + "type": "ipc" + }, + { + "type": "mount" + } + ] + }, + + "annotations": { + "com.example.key1": "value1", + "com.example.key2": "value2" + } +} From 54ed9f88dcb8d3fce981e44df29c700ec7ba9397 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Mar 2019 17:16:17 +0100 Subject: [PATCH 4/5] udev/link-config: rename MACPolicy to MACAddressPolicy Things are clearer if the same name is used everywhere, and we don't gain much by saving a few bytes. --- src/test/test-tables.c | 2 +- src/udev/net/link-config-gperf.gperf | 66 ++++++++++++++-------------- src/udev/net/link-config.c | 26 +++++------ src/udev/net/link-config.h | 22 +++++----- 4 files changed, 58 insertions(+), 58 deletions(-) diff --git a/src/test/test-tables.c b/src/test/test-tables.c index 070d1b4fe0..59f90b76ec 100644 --- a/src/test/test-tables.c +++ b/src/test/test-tables.c @@ -70,7 +70,7 @@ int main(int argc, char **argv) { test_table(kill_who, KILL_WHO); test_table(locale_variable, VARIABLE_LC); test_table(log_target, LOG_TARGET); - test_table(mac_policy, MACPOLICY); + test_table(mac_address_policy, MAC_ADDRESS_POLICY); test_table(manager_state, MANAGER_STATE); test_table(manager_timestamp, MANAGER_TIMESTAMP); test_table(mount_exec_command, MOUNT_EXEC_COMMAND); diff --git a/src/udev/net/link-config-gperf.gperf b/src/udev/net/link-config-gperf.gperf index 558996cf2e..dff849a34a 100644 --- a/src/udev/net/link-config-gperf.gperf +++ b/src/udev/net/link-config-gperf.gperf @@ -19,36 +19,36 @@ struct ConfigPerfItem; %struct-type %includes %% -Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_mac) -Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name) -Match.Path, config_parse_strv, 0, offsetof(link_config, match_path) -Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver) -Match.Type, config_parse_strv, 0, offsetof(link_config, match_type) -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, conditions) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, conditions) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, conditions) -Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, conditions) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, conditions) -Link.Description, config_parse_string, 0, offsetof(link_config, description) -Link.MACAddressPolicy, config_parse_mac_policy, 0, offsetof(link_config, mac_policy) -Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac) -Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy) -Link.Name, config_parse_ifname, 0, offsetof(link_config, name) -Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias) -Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu) -Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed) -Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex) -Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation) -Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol) -Link.Port, config_parse_port, 0, offsetof(link_config, port) -Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO]) -Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO]) -Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO6]) -Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0 -Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GRO]) -Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_LRO]) -Link.RxChannels, config_parse_channel, 0, 0 -Link.TxChannels, config_parse_channel, 0, 0 -Link.OtherChannels, config_parse_channel, 0, 0 -Link.CombinedChannels, config_parse_channel, 0, 0 -Link.Advertise, config_parse_advertise, 0, 0 +Match.MACAddress, config_parse_hwaddrs, 0, offsetof(link_config, match_mac) +Match.OriginalName, config_parse_ifnames, 0, offsetof(link_config, match_name) +Match.Path, config_parse_strv, 0, offsetof(link_config, match_path) +Match.Driver, config_parse_strv, 0, offsetof(link_config, match_driver) +Match.Type, config_parse_strv, 0, offsetof(link_config, match_type) +Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(link_config, conditions) +Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(link_config, conditions) +Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(link_config, conditions) +Match.KernelVersion, config_parse_net_condition, CONDITION_KERNEL_VERSION, offsetof(link_config, conditions) +Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(link_config, conditions) +Link.Description, config_parse_string, 0, offsetof(link_config, description) +Link.MACAddressPolicy, config_parse_mac_address_policy, 0, offsetof(link_config, mac_address_policy) +Link.MACAddress, config_parse_hwaddr, 0, offsetof(link_config, mac) +Link.NamePolicy, config_parse_name_policy, 0, offsetof(link_config, name_policy) +Link.Name, config_parse_ifname, 0, offsetof(link_config, name) +Link.Alias, config_parse_ifalias, 0, offsetof(link_config, alias) +Link.MTUBytes, config_parse_mtu, AF_UNSPEC, offsetof(link_config, mtu) +Link.BitsPerSecond, config_parse_si_size, 0, offsetof(link_config, speed) +Link.Duplex, config_parse_duplex, 0, offsetof(link_config, duplex) +Link.AutoNegotiation, config_parse_tristate, 0, offsetof(link_config, autonegotiation) +Link.WakeOnLan, config_parse_wol, 0, offsetof(link_config, wol) +Link.Port, config_parse_port, 0, offsetof(link_config, port) +Link.GenericSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GSO]) +Link.TCPSegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO]) +Link.TCP6SegmentationOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_TSO6]) +Link.UDPSegmentationOffload, config_parse_warn_compat, DISABLED_LEGACY, 0 +Link.GenericReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_GRO]) +Link.LargeReceiveOffload, config_parse_tristate, 0, offsetof(link_config, features[NET_DEV_FEAT_LRO]) +Link.RxChannels, config_parse_channel, 0, 0 +Link.TxChannels, config_parse_channel, 0, 0 +Link.OtherChannels, config_parse_channel, 0, 0 +Link.CombinedChannels, config_parse_channel, 0, 0 +Link.Advertise, config_parse_advertise, 0, 0 diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index 58d5d27883..daa737a68d 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -139,7 +139,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) { *link = (link_config) { .filename = TAKE_PTR(name), - .mac_policy = _MACPOLICY_INVALID, + .mac_address_policy = _MAC_ADDRESS_POLICY_INVALID, .wol = _WOL_INVALID, .duplex = _DUP_INVALID, .port = _NET_DEV_PORT_INVALID, @@ -280,12 +280,12 @@ int link_config_get(link_config_ctx *ctx, sd_device *device, link_config **ret) return -ENOENT; } -static int get_mac(sd_device *device, MACPolicy policy, struct ether_addr *mac) { +static int get_mac(sd_device *device, MACAddressPolicy policy, struct ether_addr *mac) { unsigned addr_type; - bool want_random = policy == MACPOLICY_RANDOM; + bool want_random = policy == MAC_ADDRESS_POLICY_RANDOM; int r; - assert(IN_SET(policy, MACPOLICY_RANDOM, MACPOLICY_PERSISTENT)); + assert(IN_SET(policy, MAC_ADDRESS_POLICY_RANDOM, MAC_ADDRESS_POLICY_PERSISTENT)); r = link_unsigned_attribute(device, "addr_assign_type", &addr_type); if (r < 0) @@ -304,7 +304,7 @@ static int get_mac(sd_device *device, MACPolicy policy, struct ether_addr *mac) if (want_random == (addr_type == NET_ADDR_RANDOM)) return log_device_debug(device, "MAC on the device already matches policy *%s*", - mac_policy_to_string(policy)); + mac_address_policy_to_string(policy)); if (want_random) { log_device_debug(device, "Using random bytes to generate MAC"); @@ -444,8 +444,8 @@ int link_config_apply(link_config_ctx *ctx, link_config *config, log_device_debug(device, "Policies didn't yield a name and Name= is not given, not renaming."); no_rename: - if (IN_SET(config->mac_policy, MACPOLICY_PERSISTENT, MACPOLICY_RANDOM)) { - if (get_mac(device, config->mac_policy, &generated_mac) > 0) + if (IN_SET(config->mac_address_policy, MAC_ADDRESS_POLICY_PERSISTENT, MAC_ADDRESS_POLICY_RANDOM)) { + if (get_mac(device, config->mac_address_policy, &generated_mac) > 0) mac = &generated_mac; } else mac = config->mac; @@ -476,14 +476,14 @@ int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret) { return 0; } -static const char* const mac_policy_table[_MACPOLICY_MAX] = { - [MACPOLICY_PERSISTENT] = "persistent", - [MACPOLICY_RANDOM] = "random", - [MACPOLICY_NONE] = "none", +static const char* const mac_address_policy_table[_MAC_ADDRESS_POLICY_MAX] = { + [MAC_ADDRESS_POLICY_PERSISTENT] = "persistent", + [MAC_ADDRESS_POLICY_RANDOM] = "random", + [MAC_ADDRESS_POLICY_NONE] = "none", }; -DEFINE_STRING_TABLE_LOOKUP(mac_policy, MACPolicy); -DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_policy, mac_policy, MACPolicy, +DEFINE_STRING_TABLE_LOOKUP(mac_address_policy, MACAddressPolicy); +DEFINE_CONFIG_PARSE_ENUM(config_parse_mac_address_policy, mac_address_policy, MACAddressPolicy, "Failed to parse MAC address policy"); static const char* const name_policy_table[_NAMEPOLICY_MAX] = { diff --git a/src/udev/net/link-config.h b/src/udev/net/link-config.h index f18b2afa79..5dfe5b59b8 100644 --- a/src/udev/net/link-config.h +++ b/src/udev/net/link-config.h @@ -12,13 +12,13 @@ typedef struct link_config_ctx link_config_ctx; typedef struct link_config link_config; -typedef enum MACPolicy { - MACPOLICY_PERSISTENT, - MACPOLICY_RANDOM, - MACPOLICY_NONE, - _MACPOLICY_MAX, - _MACPOLICY_INVALID = -1 -} MACPolicy; +typedef enum MACAddressPolicy { + MAC_ADDRESS_POLICY_PERSISTENT, + MAC_ADDRESS_POLICY_RANDOM, + MAC_ADDRESS_POLICY_NONE, + _MAC_ADDRESS_POLICY_MAX, + _MAC_ADDRESS_POLICY_INVALID = -1 +} MACAddressPolicy; typedef enum NamePolicy { NAMEPOLICY_KERNEL, @@ -44,7 +44,7 @@ struct link_config { char *description; struct ether_addr *mac; - MACPolicy mac_policy; + MACAddressPolicy mac_address_policy; NamePolicy *name_policy; char *name; char *alias; @@ -76,11 +76,11 @@ int link_get_driver(link_config_ctx *ctx, sd_device *device, char **ret); const char *name_policy_to_string(NamePolicy p) _const_; NamePolicy name_policy_from_string(const char *p) _pure_; -const char *mac_policy_to_string(MACPolicy p) _const_; -MACPolicy mac_policy_from_string(const char *p) _pure_; +const char *mac_address_policy_to_string(MACAddressPolicy p) _const_; +MACAddressPolicy mac_address_policy_from_string(const char *p) _pure_; /* gperf lookup function */ const struct ConfigPerfItem* link_config_gperf_lookup(const char *key, GPERF_LEN_TYPE length); -CONFIG_PARSER_PROTOTYPE(config_parse_mac_policy); +CONFIG_PARSER_PROTOTYPE(config_parse_mac_address_policy); CONFIG_PARSER_PROTOTYPE(config_parse_name_policy); From b2645747b7b4698ef93beb81a00ba5daaa0b1406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= Date: Fri, 22 Mar 2019 17:23:49 +0100 Subject: [PATCH 5/5] nspawn-oci: fix double free Also rename function to make it clear that it also frees the array object itself. --- src/nspawn/nspawn-settings.c | 5 ++--- src/nspawn/nspawn-settings.h | 2 +- src/nspawn/nspawn.c | 4 ++-- .../crash-bffbd2085d4e95c47e9749b3f4a2dbc0580c20d3 | 5 +++++ 4 files changed, 10 insertions(+), 6 deletions(-) create mode 100644 test/fuzz/fuzz-nspawn-oci/crash-bffbd2085d4e95c47e9749b3f4a2dbc0580c20d3 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 f3842f70c6..8e6780d54b 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; @@ -5070,7 +5070,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; diff --git a/test/fuzz/fuzz-nspawn-oci/crash-bffbd2085d4e95c47e9749b3f4a2dbc0580c20d3 b/test/fuzz/fuzz-nspawn-oci/crash-bffbd2085d4e95c47e9749b3f4a2dbc0580c20d3 new file mode 100644 index 0000000000..22e42d3bad --- /dev/null +++ b/test/fuzz/fuzz-nspawn-oci/crash-bffbd2085d4e95c47e9749b3f4a2dbc0580c20d3 @@ -0,0 +1,5 @@ +{"ociVersion": "1.0.0", +"linux": {"devices": [ { "access": "mmmw;r"} +] }, "e": "}e" + } + \ No newline at end of file