libnl3/libnl3-route-fix-handling-old_nh-in-rtnl_route_parse-and-av.patch

122 lines
3.5 KiB
Diff
Raw Normal View History

2019-09-30 10:57:19 -04:00
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