summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSimon Chopin <87005181+schopin-pro@users.noreply.github.com>2021-07-21 10:27:45 +0200
committerLukas Märdian <slyon@ubuntu.com>2021-08-04 13:39:20 +0200
commita5bec5b5ca3b7cea4bf68b130d1cc1f84fe7f2df (patch)
tree998ab219d0542a9712c257a303bd1fa6cc6a7f06 /src
parent356d06fd05ff446004886745cdba55a9de7c9883 (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.c27
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[] = {