diff options
author | Simon Chopin <87005181+schopin-pro@users.noreply.github.com> | 2021-07-21 10:27:45 +0200 |
---|---|---|
committer | Lukas Märdian <slyon@ubuntu.com> | 2021-08-04 13:39:20 +0200 |
commit | a5bec5b5ca3b7cea4bf68b130d1cc1f84fe7f2df (patch) | |
tree | 998ab219d0542a9712c257a303bd1fa6cc6a7f06 /src | |
parent | 356d06fd05ff446004886745cdba55a9de7c9883 (diff) |
parse: handle_routes: clean up the route on error (#219)
This patch reworks the single route processing to only append the parsed
route to the interface when it has been fully validated, and use a
single error path otherwise. This allows us to locally control the
cleanup and freeing of the allocated route.
The previous version could indeed leak if process_mapping returned an
error (and that's assuming that the interface cleanup process would free
up the routes already assigned, which I haven't checked).
Diffstat (limited to 'src')
-rw-r--r-- | src/parse.c | 27 |
1 files changed, 16 insertions, 11 deletions
diff --git a/src/parse.c b/src/parse.c index ddd531b..303ab66 100644 --- a/src/parse.c +++ b/src/parse.c @@ -1643,30 +1643,35 @@ handle_routes(yaml_document_t* doc, yaml_node_t* node, const void* _, GError** e cur_route->metric = NETPLAN_METRIC_UNSPEC; /* 0 is a valid metric */ g_debug("%s: adding new route", cur_netdef->id); - if (process_mapping(doc, entry, routes_handlers, NULL, error)) - g_array_append_val(cur_netdef->routes, cur_route); + if (!process_mapping(doc, entry, routes_handlers, NULL, error)) + goto err; if ( ( g_ascii_strcasecmp(cur_route->scope, "link") == 0 || g_ascii_strcasecmp(cur_route->scope, "host") == 0) && !cur_route->to) { - cur_route = NULL; - return yaml_error(node, error, "link and host routes must specify a 'to' IP"); + yaml_error(node, error, "link and host routes must specify a 'to' IP"); + goto err; } else if ( g_ascii_strcasecmp(cur_route->type, "unicast") == 0 && g_ascii_strcasecmp(cur_route->scope, "global") == 0 && (!cur_route->to || !cur_route->via)) { - cur_route = NULL; - return yaml_error(node, error, "unicast route must include both a 'to' and 'via' IP"); + yaml_error(node, error, "unicast route must include both a 'to' and 'via' IP"); + goto err; } else if (g_ascii_strcasecmp(cur_route->type, "unicast") != 0 && !cur_route->to) { - cur_route = NULL; - return yaml_error(node, error, "non-unicast routes must specify a 'to' IP"); + yaml_error(node, error, "non-unicast routes must specify a 'to' IP"); + goto err; } + g_array_append_val(cur_netdef->routes, cur_route); cur_route = NULL; - - if (error && *error) - return FALSE; } return TRUE; + +err: + if (cur_route) { + g_free(cur_route); + cur_route = NULL; + } + return FALSE; } static const mapping_entry_handler ip_rules_handlers[] = { |