summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2019-02-21 08:37:40 +0100
committerThomas Haller <thaller@redhat.com>2019-02-22 10:05:00 +0100
commit60e4595101fd3f0ce6193ef87320c94641779708 (patch)
treecb9b0fcc73b0f6fdf885dbf20b7f62ef2f934c43
parent1b7e89ad7d286c03c036ccb0d87f5063ffc068b3 (diff)
downloadNetworkManager-60e4595101fd3f0ce6193ef87320c94641779708.tar.gz
platform: cleanup parsing of RTA_MULTIPATH in _new_from_nl_route()
I think the code before was correct. At the very least because we only run the while-loop at most once because multipath routes are not supported. However, it seems odd that the while loop checks for "tlen >= rtnh->rtnh_len" but later we do "tlen -= RTNH_ALIGN (rtnh->rtnh_len)" Well, arguably, tlen itself is aligned to 4 bytes (as kernel sends the netlink message that way). So, it was indeed fine. Still, confusing. Try to check more explicitly for the buffer sizes.
-rw-r--r--src/platform/nm-linux-platform.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c
index 1fa0c451e5..6b5ee8635c 100644
--- a/src/platform/nm-linux-platform.c
+++ b/src/platform/nm-linux-platform.c
@@ -3148,18 +3148,25 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
*****************************************************************/
if (tb[RTA_MULTIPATH]) {
- struct rtnexthop *rtnh = nla_data (tb[RTA_MULTIPATH]);
size_t tlen = nla_len (tb[RTA_MULTIPATH]);
+ struct rtnexthop *rtnh;
- while ( tlen >= sizeof (*rtnh)
- && tlen >= rtnh->rtnh_len) {
+ if (tlen < sizeof (*rtnh))
+ goto rta_multipath_done;
+
+ rtnh = nla_data_as (struct rtnexthop, tb[RTA_MULTIPATH]);
+
+ if (tlen < rtnh->rtnh_len)
+ goto rta_multipath_done;
+
+ while (TRUE) {
if (nh.is_present) {
/* we don't support multipath routes. */
return NULL;
}
- nh.is_present = TRUE;
+ nh.is_present = TRUE;
nh.ifindex = rtnh->rtnh_ifindex;
if (rtnh->rtnh_len > sizeof (*rtnh)) {
@@ -3175,9 +3182,14 @@ _new_from_nl_route (struct nlmsghdr *nlh, gboolean id_only)
memcpy (&nh.gateway, nla_data (ntb[RTA_GATEWAY]), addr_len);
}
+ if (tlen < RTNH_ALIGN (rtnh->rtnh_len) + sizeof (*rtnh))
+ goto rta_multipath_done;
+
tlen -= RTNH_ALIGN (rtnh->rtnh_len);
rtnh = RTNH_NEXT (rtnh);
}
+rta_multipath_done:
+ ;
}
if ( tb[RTA_OIF]