diff options
author | Thomas Haller <thaller@redhat.com> | 2019-02-21 08:37:40 +0100 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2019-02-22 10:05:00 +0100 |
commit | 60e4595101fd3f0ce6193ef87320c94641779708 (patch) | |
tree | cb9b0fcc73b0f6fdf885dbf20b7f62ef2f934c43 | |
parent | 1b7e89ad7d286c03c036ccb0d87f5063ffc068b3 (diff) | |
download | NetworkManager-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.c | 20 |
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] |