122 lines
3.5 KiB
Diff
122 lines
3.5 KiB
Diff
From 1228a65963956300bd0466437530b975e0eaeec5 Mon Sep 17 00:00:00 2001
|
|
From: Thomas Haller <thaller@redhat.com>
|
|
Date: Mon, 6 Nov 2017 15:04:14 +0100
|
|
Subject: [PATCH 08/76] route: fix handling old_nh in rtnl_route_parse() and
|
|
avoid leak
|
|
|
|
The previous code would miss to release old_nh in the error
|
|
path.
|
|
|
|
Also, it relied on the present netlink attributes to have old_nh
|
|
initialized. Don't do that.
|
|
|
|
Also, fixup error codes by using "goto errout_nomem" where appropriate
|
|
and keep @err as returned from rtnl_route_set_metric().
|
|
---
|
|
lib/route/route_obj.c | 28 ++++++++++++++++++++--------
|
|
1 file changed, 20 insertions(+), 8 deletions(-)
|
|
|
|
diff --git a/lib/route/route_obj.c b/lib/route/route_obj.c
|
|
index 8ae6b89..bc62408 100644
|
|
--- a/lib/route/route_obj.c
|
|
+++ b/lib/route/route_obj.c
|
|
@@ -1125,10 +1125,8 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
int err, family;
|
|
|
|
route = rtnl_route_alloc();
|
|
- if (!route) {
|
|
- err = -NLE_NOMEM;
|
|
- goto errout;
|
|
- }
|
|
+ if (!route)
|
|
+ goto errout_nomem;
|
|
|
|
route->ce_msgtype = nlh->nlmsg_type;
|
|
|
|
@@ -1213,7 +1211,9 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
for (i = 1; i <= RTAX_MAX; i++) {
|
|
if (mtb[i] && nla_len(mtb[i]) >= sizeof(uint32_t)) {
|
|
uint32_t m = nla_get_u32(mtb[i]);
|
|
- if (rtnl_route_set_metric(route, i, m) < 0)
|
|
+
|
|
+ err = rtnl_route_set_metric(route, i, m);
|
|
+ if (err < 0)
|
|
goto errout;
|
|
}
|
|
}
|
|
@@ -1231,14 +1231,14 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
|
|
if (tb[RTA_OIF]) {
|
|
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
|
|
- goto errout;
|
|
+ goto errout_nomem;
|
|
|
|
rtnl_route_nh_set_ifindex(old_nh, nla_get_u32(tb[RTA_OIF]));
|
|
}
|
|
|
|
if (tb[RTA_GATEWAY]) {
|
|
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
|
|
- goto errout;
|
|
+ goto errout_nomem;
|
|
|
|
if (!(addr = nl_addr_alloc_attr(tb[RTA_GATEWAY], family)))
|
|
goto errout_nomem;
|
|
@@ -1249,7 +1249,7 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
|
|
if (tb[RTA_FLOW]) {
|
|
if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
|
|
- goto errout;
|
|
+ goto errout_nomem;
|
|
|
|
rtnl_route_nh_set_realms(old_nh, nla_get_u32(tb[RTA_FLOW]));
|
|
}
|
|
@@ -1257,6 +1257,9 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
if (tb[RTA_NEWDST]) {
|
|
struct nl_addr *addr;
|
|
|
|
+ if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
|
|
+ goto errout_nomem;
|
|
+
|
|
addr = nl_addr_alloc_attr(tb[RTA_NEWDST], route->rt_family);
|
|
if (!addr)
|
|
goto errout_nomem;
|
|
@@ -1271,6 +1274,9 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
int alen = nla_len(tb[RTA_VIA]) - offsetof(struct rtvia, rtvia_addr);
|
|
struct rtvia *via = nla_data(tb[RTA_VIA]);
|
|
|
|
+ if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
|
|
+ goto errout_nomem;
|
|
+
|
|
addr = nl_addr_build(via->rtvia_family, via->rtvia_addr, alen);
|
|
if (!addr)
|
|
goto errout_nomem;
|
|
@@ -1287,6 +1293,9 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
}
|
|
|
|
if (tb[RTA_ENCAP] && tb[RTA_ENCAP_TYPE]) {
|
|
+ if (!old_nh && !(old_nh = rtnl_route_nh_alloc()))
|
|
+ goto errout_nomem;
|
|
+
|
|
err = nh_encap_parse_msg(tb[RTA_ENCAP],
|
|
tb[RTA_ENCAP_TYPE], old_nh);
|
|
if (err)
|
|
@@ -1319,12 +1328,15 @@ int rtnl_route_parse(struct nlmsghdr *nlh, struct rtnl_route **result)
|
|
|
|
rtnl_route_nh_free(old_nh);
|
|
}
|
|
+ old_nh = NULL;
|
|
}
|
|
|
|
*result = route;
|
|
return 0;
|
|
|
|
errout:
|
|
+ if (old_nh)
|
|
+ rtnl_route_nh_free(old_nh);
|
|
rtnl_route_put(route);
|
|
return err;
|
|
|
|
--
|
|
1.8.3.1
|
|
|