diff --git a/SOURCES/0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch b/SOURCES/0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch new file mode 100644 index 0000000..14774b6 --- /dev/null +++ b/SOURCES/0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch @@ -0,0 +1,52 @@ +From d80837df37cb8897769f87f7a2034a9653168221 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 21 Feb 2019 14:38:57 +0100 +Subject: [PATCH] iproute: Abort if nexthop cannot be parsed + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 +Upstream Status: iproute2.git commit ee53b42fd8b0b + +commit ee53b42fd8b0b0cdb857d0f5bf7467e22a3457d9 +Author: Jakub Sitnicki +Date: Wed Apr 11 11:43:11 2018 +0200 + + iproute: Abort if nexthop cannot be parsed + + Attempt to add a multipath route where a nexthop definition refers to a + non-existent device causes 'ip' to crash and burn due to stack buffer + overflow: + + # ip -6 route add fd00::1/64 nexthop dev fake1 + Cannot find device "fake1" + Cannot find device "fake1" + Cannot find device "fake1" + ... + Segmentation fault (core dumped) + + Don't ignore errors from the helper routine that parses the nexthop + definition, and abort immediately if parsing fails. + + Signed-off-by: Jakub Sitnicki +--- + ip/iproute.c | 5 ++++- + 1 file changed, 4 insertions(+), 1 deletion(-) + +diff --git a/ip/iproute.c b/ip/iproute.c +index 35fdce8..759032d 100644 +--- a/ip/iproute.c ++++ b/ip/iproute.c +@@ -817,7 +817,10 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, + memset(rtnh, 0, sizeof(*rtnh)); + rtnh->rtnh_len = sizeof(*rtnh); + rta->rta_len += rtnh->rtnh_len; +- parse_one_nh(n, r, rta, rtnh, &argc, &argv); ++ if (parse_one_nh(n, r, rta, rtnh, &argc, &argv)) { ++ fprintf(stderr, "Error: cannot parse nexthop\n"); ++ exit(-1); ++ } + rtnh = RTNH_NEXT(rtnh); + } + +-- +1.8.3.1 + diff --git a/SOURCES/0051-ip-route-Fix-segfault-with-many-nexthops.patch b/SOURCES/0051-ip-route-Fix-segfault-with-many-nexthops.patch new file mode 100644 index 0000000..07109f0 --- /dev/null +++ b/SOURCES/0051-ip-route-Fix-segfault-with-many-nexthops.patch @@ -0,0 +1,388 @@ +From 5845a145808162560293cf4f7c55bbb5afc8dce7 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 21 Feb 2019 14:38:57 +0100 +Subject: [PATCH] ip-route: Fix segfault with many nexthops + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 +Upstream Status: iproute2.git commit bd59e5b1517b0 +Conflicts: Context changes due to missing other commits. + +commit bd59e5b1517b09b6f26d59f38fe6077d953c2396 +Author: Phil Sutter +Date: Thu Sep 6 15:31:51 2018 +0200 + + ip-route: Fix segfault with many nexthops + + It was possible to crash ip-route by adding an IPv6 route with 37 + nexthop statements. A simple reproducer is: + + | for i in `seq 37`; do + | nhs="nexthop via 1111::$i "$nhs + | done + | ip -6 route add 3333::/64 $nhs + + The related code was broken in multiple ways: + + * parse_one_nh() assumed that rta points to 4kB of storage but caller + provided just 1kB. Fixed by passing 'len' parameter with the correct + value. + + * Error checking of rta_addattr*() calls in parse_one_nh() and called + functions was completely absent, so with above fix in place output + flood would occur due to parser looping forever. + + While being at it, increase message buffer sizes to 4k. This allows for + at most 144 nexthops. + + Signed-off-by: Phil Sutter + Signed-off-by: Stephen Hemminger +--- + ip/iproute.c | 43 +++++++++++++++++++++-------------- + ip/iproute_lwtunnel.c | 63 ++++++++++++++++++++++++++++++++------------------- + 2 files changed, 66 insertions(+), 40 deletions(-) + +diff --git a/ip/iproute.c b/ip/iproute.c +index 759032d..d4db035 100644 +--- a/ip/iproute.c ++++ b/ip/iproute.c +@@ -721,7 +721,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg) + } + + static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, +- struct rtattr *rta, struct rtnexthop *rtnh, ++ struct rtattr *rta, size_t len, struct rtnexthop *rtnh, + int *argcp, char ***argvp) + { + int argc = *argcp; +@@ -742,11 +742,16 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, + if (r->rtm_family == AF_UNSPEC) + r->rtm_family = addr.family; + if (addr.family == r->rtm_family) { +- rta_addattr_l(rta, 4096, RTA_GATEWAY, &addr.data, addr.bytelen); +- rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen; ++ if (rta_addattr_l(rta, len, RTA_GATEWAY, ++ &addr.data, addr.bytelen)) ++ return -1; ++ rtnh->rtnh_len += sizeof(struct rtattr) ++ + addr.bytelen; + } else { +- rta_addattr_l(rta, 4096, RTA_VIA, &addr.family, addr.bytelen+2); +- rtnh->rtnh_len += RTA_SPACE(addr.bytelen+2); ++ if (rta_addattr_l(rta, len, RTA_VIA, ++ &addr.family, addr.bytelen + 2)) ++ return -1; ++ rtnh->rtnh_len += RTA_SPACE(addr.bytelen + 2); + } + } else if (strcmp(*argv, "dev") == 0) { + NEXT_ARG(); +@@ -769,13 +774,15 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, + NEXT_ARG(); + if (get_rt_realms_or_raw(&realm, *argv)) + invarg("\"realm\" value is invalid\n", *argv); +- rta_addattr32(rta, 4096, RTA_FLOW, realm); ++ if (rta_addattr32(rta, len, RTA_FLOW, realm)) ++ return -1; + rtnh->rtnh_len += sizeof(struct rtattr) + 4; + } else if (strcmp(*argv, "encap") == 0) { +- int len = rta->rta_len; ++ int old_len = rta->rta_len; + +- lwt_parse_encap(rta, 4096, &argc, &argv); +- rtnh->rtnh_len += rta->rta_len - len; ++ if (lwt_parse_encap(rta, len, &argc, &argv)) ++ return -1; ++ rtnh->rtnh_len += rta->rta_len - old_len; + } else if (strcmp(*argv, "as") == 0) { + inet_prefix addr; + +@@ -783,8 +790,9 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, + if (strcmp(*argv, "to") == 0) + NEXT_ARG(); + get_addr(&addr, *argv, r->rtm_family); +- rta_addattr_l(rta, 4096, RTA_NEWDST, &addr.data, +- addr.bytelen); ++ if (rta_addattr_l(rta, len, RTA_NEWDST, ++ &addr.data, addr.bytelen)) ++ return -1; + rtnh->rtnh_len += sizeof(struct rtattr) + addr.bytelen; + } else + break; +@@ -797,7 +805,7 @@ static int parse_one_nh(struct nlmsghdr *n, struct rtmsg *r, + static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, + int argc, char **argv) + { +- char buf[1024]; ++ char buf[4096]; + struct rtattr *rta = (void *)buf; + struct rtnexthop *rtnh; + +@@ -817,7 +825,7 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, + memset(rtnh, 0, sizeof(*rtnh)); + rtnh->rtnh_len = sizeof(*rtnh); + rta->rta_len += rtnh->rtnh_len; +- if (parse_one_nh(n, r, rta, rtnh, &argc, &argv)) { ++ if (parse_one_nh(n, r, rta, 4096, rtnh, &argc, &argv)) { + fprintf(stderr, "Error: cannot parse nexthop\n"); + exit(-1); + } +@@ -825,7 +833,8 @@ static int parse_nexthops(struct nlmsghdr *n, struct rtmsg *r, + } + + if (rta->rta_len > RTA_LENGTH(0)) +- addattr_l(n, 1024, RTA_MULTIPATH, RTA_DATA(rta), RTA_PAYLOAD(rta)); ++ return addattr_l(n, 4096, RTA_MULTIPATH, ++ RTA_DATA(rta), RTA_PAYLOAD(rta)); + return 0; + } + +@@ -834,7 +843,7 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) + struct { + struct nlmsghdr n; + struct rtmsg r; +- char buf[1024]; ++ char buf[4096]; + } req = { + .n.nlmsg_len = NLMSG_LENGTH(sizeof(struct rtmsg)), + .n.nlmsg_flags = NLM_F_REQUEST | flags, +@@ -1238,8 +1247,8 @@ static int iproute_modify(int cmd, unsigned int flags, int argc, char **argv) + addattr_l(&req.n, sizeof(req), RTA_METRICS, RTA_DATA(mxrta), RTA_PAYLOAD(mxrta)); + } + +- if (nhs_ok) +- parse_nexthops(&req.n, &req.r, argc, argv); ++ if (nhs_ok && parse_nexthops(&req.n, &req.r, argc, argv)) ++ return -1; + + if (req.r.rtm_family == AF_UNSPEC) + req.r.rtm_family = AF_INET; +diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c +index 0fa1cab..1a68912 100644 +--- a/ip/iproute_lwtunnel.c ++++ b/ip/iproute_lwtunnel.c +@@ -255,8 +255,9 @@ static int parse_encap_mpls(struct rtattr *rta, size_t len, + exit(1); + } + +- rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST, &addr.data, +- addr.bytelen); ++ if (rta_addattr_l(rta, len, MPLS_IPTUNNEL_DST, ++ &addr.data, addr.bytelen)) ++ return -1; + + *argcp = argc; + *argvp = argv; +@@ -270,6 +271,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, + int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0; + char **argv = *argvp; + int argc = *argcp; ++ int ret = 0; + + while (argc > 0) { + if (strcmp(*argv, "id") == 0) { +@@ -280,7 +282,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, + duparg2("id", *argv); + if (get_be64(&id, *argv, 0)) + invarg("\"id\" value is invalid\n", *argv); +- rta_addattr64(rta, len, LWTUNNEL_IP_ID, id); ++ ret = rta_addattr64(rta, len, LWTUNNEL_IP_ID, id); + } else if (strcmp(*argv, "dst") == 0) { + inet_prefix addr; + +@@ -288,8 +290,8 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, + if (dst_ok++) + duparg2("dst", *argv); + get_addr(&addr, *argv, AF_INET); +- rta_addattr_l(rta, len, LWTUNNEL_IP_DST, +- &addr.data, addr.bytelen); ++ ret = rta_addattr_l(rta, len, LWTUNNEL_IP_DST, ++ &addr.data, addr.bytelen); + } else if (strcmp(*argv, "tos") == 0) { + __u32 tos; + +@@ -298,7 +300,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, + duparg2("tos", *argv); + if (rtnl_dsfield_a2n(&tos, *argv)) + invarg("\"tos\" value is invalid\n", *argv); +- rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos); ++ ret = rta_addattr8(rta, len, LWTUNNEL_IP_TOS, tos); + } else if (strcmp(*argv, "ttl") == 0) { + __u8 ttl; + +@@ -307,10 +309,12 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, + duparg2("ttl", *argv); + if (get_u8(&ttl, *argv, 0)) + invarg("\"ttl\" value is invalid\n", *argv); +- rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl); ++ ret = rta_addattr8(rta, len, LWTUNNEL_IP_TTL, ttl); + } else { + break; + } ++ if (ret) ++ break; + argc--; argv++; + } + +@@ -321,7 +325,7 @@ static int parse_encap_ip(struct rtattr *rta, size_t len, + *argcp = argc + 1; + *argvp = argv - 1; + +- return 0; ++ return ret; + } + + static int parse_encap_ila(struct rtattr *rta, size_t len, +@@ -330,6 +334,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, + __u64 locator; + int argc = *argcp; + char **argv = *argvp; ++ int ret = 0; + + if (get_addr64(&locator, *argv) < 0) { + fprintf(stderr, "Bad locator: %s\n", *argv); +@@ -338,7 +343,8 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, + + argc--; argv++; + +- rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator); ++ if (rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator)) ++ return -1; + + while (argc > 0) { + if (strcmp(*argv, "csum-mode") == 0) { +@@ -351,12 +357,15 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, + invarg("\"csum-mode\" value is invalid\n", + *argv); + +- rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, csum_mode); ++ ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, ++ (__u8)csum_mode); + + argc--; argv++; + } else { + break; + } ++ if (ret) ++ break; + } + + /* argv is currently the first unparsed argument, +@@ -366,7 +375,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, + *argcp = argc + 1; + *argvp = argv - 1; + +- return 0; ++ return ret; + } + + static int parse_encap_ip6(struct rtattr *rta, size_t len, +@@ -375,6 +384,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, + int id_ok = 0, dst_ok = 0, tos_ok = 0, ttl_ok = 0; + char **argv = *argvp; + int argc = *argcp; ++ int ret = 0; + + while (argc > 0) { + if (strcmp(*argv, "id") == 0) { +@@ -385,7 +395,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, + duparg2("id", *argv); + if (get_be64(&id, *argv, 0)) + invarg("\"id\" value is invalid\n", *argv); +- rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id); ++ ret = rta_addattr64(rta, len, LWTUNNEL_IP6_ID, id); + } else if (strcmp(*argv, "dst") == 0) { + inet_prefix addr; + +@@ -393,8 +403,8 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, + if (dst_ok++) + duparg2("dst", *argv); + get_addr(&addr, *argv, AF_INET6); +- rta_addattr_l(rta, len, LWTUNNEL_IP6_DST, +- &addr.data, addr.bytelen); ++ ret = rta_addattr_l(rta, len, LWTUNNEL_IP6_DST, ++ &addr.data, addr.bytelen); + } else if (strcmp(*argv, "tc") == 0) { + __u32 tc; + +@@ -403,7 +413,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, + duparg2("tc", *argv); + if (rtnl_dsfield_a2n(&tc, *argv)) + invarg("\"tc\" value is invalid\n", *argv); +- rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc); ++ ret = rta_addattr8(rta, len, LWTUNNEL_IP6_TC, tc); + } else if (strcmp(*argv, "hoplimit") == 0) { + __u8 hoplimit; + +@@ -413,10 +423,13 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, + if (get_u8(&hoplimit, *argv, 0)) + invarg("\"hoplimit\" value is invalid\n", + *argv); +- rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, hoplimit); ++ ret = rta_addattr8(rta, len, LWTUNNEL_IP6_HOPLIMIT, ++ hoplimit); + } else { + break; + } ++ if (ret) ++ break; + argc--; argv++; + } + +@@ -427,7 +440,7 @@ static int parse_encap_ip6(struct rtattr *rta, size_t len, + *argcp = argc + 1; + *argvp = argv - 1; + +- return 0; ++ return ret; + } + + struct lwt_x { +@@ -542,6 +555,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) + int argc = *argcp; + char **argv = *argvp; + __u16 type; ++ int ret = 0; + + NEXT_ARG(); + type = read_encap_type(*argv); +@@ -558,16 +572,16 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) + nest = rta_nest(rta, 1024, RTA_ENCAP); + switch (type) { + case LWTUNNEL_ENCAP_MPLS: +- parse_encap_mpls(rta, len, &argc, &argv); ++ ret = parse_encap_mpls(rta, len, &argc, &argv); + break; + case LWTUNNEL_ENCAP_IP: +- parse_encap_ip(rta, len, &argc, &argv); ++ ret = parse_encap_ip(rta, len, &argc, &argv); + break; + case LWTUNNEL_ENCAP_ILA: +- parse_encap_ila(rta, len, &argc, &argv); ++ ret = parse_encap_ila(rta, len, &argc, &argv); + break; + case LWTUNNEL_ENCAP_IP6: +- parse_encap_ip6(rta, len, &argc, &argv); ++ ret = parse_encap_ip6(rta, len, &argc, &argv); + break; + case LWTUNNEL_ENCAP_BPF: + if (parse_encap_bpf(rta, len, &argc, &argv) < 0) +@@ -577,12 +591,15 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) + fprintf(stderr, "Error: unsupported encap type\n"); + break; + } ++ if (ret) ++ return ret; ++ + rta_nest_end(rta, nest); + +- rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); ++ ret = rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); + + *argcp = argc; + *argvp = argv; + +- return 0; ++ return ret; + } +-- +1.8.3.1 + diff --git a/SOURCES/0052-man-ip-route.8-Document-nexthop-limit.patch b/SOURCES/0052-man-ip-route.8-Document-nexthop-limit.patch new file mode 100644 index 0000000..cc483b9 --- /dev/null +++ b/SOURCES/0052-man-ip-route.8-Document-nexthop-limit.patch @@ -0,0 +1,46 @@ +From d511d7e60866060e260ec3f96b51a61c98c2c06f Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 21 Feb 2019 14:39:46 +0100 +Subject: [PATCH] man: ip-route.8: Document nexthop limit + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 +Upstream Status: iproute2.git commit 6cd959bb125c5 + +commit 6cd959bb125c50a04ab6671645fa38c5b07426f4 +Author: Phil Sutter +Date: Tue Nov 13 16:55:13 2018 +0100 + + man: ip-route.8: Document nexthop limit + + Add a note to 'nexthop' description stating the maximum number of + nexthops per command and pointing at 'append' command as a workaround. + + Signed-off-by: Phil Sutter + Signed-off-by: Stephen Hemminger +--- + man/man8/ip-route.8.in | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/man/man8/ip-route.8.in b/man/man8/ip-route.8.in +index d6e0664..d9a5477 100644 +--- a/man/man8/ip-route.8.in ++++ b/man/man8/ip-route.8.in +@@ -548,6 +548,15 @@ argument lists: + route reflecting its relative bandwidth or quality. + .in -8 + ++The internal buffer used in iproute2 limits the maximum number of nexthops that ++may be specified in one go. If only ++.I ADDRESS ++is given, the current buffer size allows for 144 IPv6 nexthops and 253 IPv4 ++ones. For IPv4, this effectively limits the number of nexthops possible per ++route. With IPv6, further nexthops may be appended to the same route via ++.B "ip route append" ++command. ++ + .TP + .BI scope " SCOPE_VAL" + the scope of the destinations covered by the route prefix. +-- +1.8.3.1 + diff --git a/SOURCES/0053-ip-route-Fix-nexthop-encap-parsing.patch b/SOURCES/0053-ip-route-Fix-nexthop-encap-parsing.patch new file mode 100644 index 0000000..ff535eb --- /dev/null +++ b/SOURCES/0053-ip-route-Fix-nexthop-encap-parsing.patch @@ -0,0 +1,85 @@ +From b83b0767eccfb386406ccb24130b975f1c2b0ee4 Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Thu, 21 Feb 2019 14:39:47 +0100 +Subject: [PATCH] ip-route: Fix nexthop encap parsing + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1624656 +Upstream Status: iproute2.git commit 05d978e0850a6 +Conflicts: Some chunks dropped due to missing support for + ident-type and hook-type. + +commit 05d978e0850a6a3bae1e6c5392d82f7b1496f86a +Author: Phil Sutter +Date: Tue Nov 13 13:39:04 2018 +0100 + + ip-route: Fix nexthop encap parsing + + When parsing nexthop parameters, a buffer of 4k bytes is provided. Yet, + in lwt_parse_encap() and some functions called by it, buffer size was + assumed to be 1k despite the actual size was provided. This led to + spurious buffer size errors if the buffer was filled by previous nexthop + parameters to exceed that 1k boundary. + + Fixes: 1e5293056a02c ("lwtunnel: Add encapsulation support to ip route") + Fixes: 5866bddd9aa9e ("ila: Add support for ILA lwtunnels") + Fixes: ed67f83806538 ("ila: Support for checksum neutral translation") + Fixes: 86905c8f057c0 ("ila: support for configuring identifier and hook types") + Fixes: b15f440e78373 ("lwt: BPF support for LWT") + Signed-off-by: Phil Sutter + Signed-off-by: Stephen Hemminger +--- + ip/iproute_lwtunnel.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/ip/iproute_lwtunnel.c b/ip/iproute_lwtunnel.c +index 1a68912..b6f08f0 100644 +--- a/ip/iproute_lwtunnel.c ++++ b/ip/iproute_lwtunnel.c +@@ -343,7 +343,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, + + argc--; argv++; + +- if (rta_addattr64(rta, 1024, ILA_ATTR_LOCATOR, locator)) ++ if (rta_addattr64(rta, len, ILA_ATTR_LOCATOR, locator)) + return -1; + + while (argc > 0) { +@@ -357,7 +357,7 @@ static int parse_encap_ila(struct rtattr *rta, size_t len, + invarg("\"csum-mode\" value is invalid\n", + *argv); + +- ret = rta_addattr8(rta, 1024, ILA_ATTR_CSUM_MODE, ++ ret = rta_addattr8(rta, len, ILA_ATTR_CSUM_MODE, + (__u8)csum_mode); + + argc--; argv++; +@@ -528,7 +528,7 @@ static int parse_encap_bpf(struct rtattr *rta, size_t len, int *argcp, + if (get_unsigned(&headroom, *argv, 0) || headroom == 0) + invarg("headroom is invalid\n", *argv); + if (!headroom_set) +- rta_addattr32(rta, 1024, LWT_BPF_XMIT_HEADROOM, ++ rta_addattr32(rta, len, LWT_BPF_XMIT_HEADROOM, + headroom); + headroom_set = 1; + } else if (strcmp(*argv, "help") == 0) { +@@ -569,7 +569,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) + exit(-1); + } + +- nest = rta_nest(rta, 1024, RTA_ENCAP); ++ nest = rta_nest(rta, len, RTA_ENCAP); + switch (type) { + case LWTUNNEL_ENCAP_MPLS: + ret = parse_encap_mpls(rta, len, &argc, &argv); +@@ -596,7 +596,7 @@ int lwt_parse_encap(struct rtattr *rta, size_t len, int *argcp, char ***argvp) + + rta_nest_end(rta, nest); + +- ret = rta_addattr16(rta, 1024, RTA_ENCAP_TYPE, type); ++ ret = rta_addattr16(rta, len, RTA_ENCAP_TYPE, type); + + *argcp = argc; + *argvp = argv; +-- +1.8.3.1 + diff --git a/SOURCES/0054-ip-link-Fix-listing-of-alias-interfaces.patch b/SOURCES/0054-ip-link-Fix-listing-of-alias-interfaces.patch new file mode 100644 index 0000000..534b391 --- /dev/null +++ b/SOURCES/0054-ip-link-Fix-listing-of-alias-interfaces.patch @@ -0,0 +1,57 @@ +From eb3be709aece2325f7eafc113120cf5ef8f077de Mon Sep 17 00:00:00 2001 +From: Phil Sutter +Date: Mon, 11 Mar 2019 16:28:41 +0100 +Subject: [PATCH] ip-link: Fix listing of alias interfaces + +Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1673226 +Upstream Status: RHEL-only +Conflicts: Context change due to missing commit 260137e24d3b7 + ("iplink: Remove flags argument from iplink_get") + +Upstream rejected this patch as the alias notation is neither required +nor wanted by iproute2[1]. With iproute rebase in RHEL7.5 though, we +changed existing behaviour by accident. Therefore we will carry this +patch for RHEL7 lifetime. + +[1] https://marc.info/?l=linux-netdev&m=154964861913609&w=2 + +commit a1259acb3c2037f464e31fad1f21556f8bf58c91 +Author: Phil Sutter +Date: Thu Feb 7 10:18:16 2019 +0100 + + ip-link: Fix listing of alias interfaces + + Commit 50b9950dd9011 ("link dump filter") accidentally broke listing of + links in the old alias interface notation: + + | % ip link show eth0:1 + | RTNETLINK answers: No such device + | Cannot send link get request: No such device + + Prior to the above commit, link lookup was performed via ifindex + returned by if_nametoindex(). The latter uses SIOCGIFINDEX ioctl call + which on kernel side causes the colon-suffix to be dropped before doing + the interface lookup. Netlink API though doesn't care about that at all. + To keep things backward compatible, mimick ioctl API behaviour and drop + the colon-suffix prior to sending the RTM_GETLINK request. + + Fixes: 50b9950dd9011 ("link dump filter") +--- + ip/ipaddress.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/ip/ipaddress.c b/ip/ipaddress.c +index 7492075..14e9e22 100644 +--- a/ip/ipaddress.c ++++ b/ip/ipaddress.c +@@ -1707,6 +1707,7 @@ static int ipaddr_list_flush_or_save(int argc, char **argv, int action) + * the link device + */ + if (filter_dev && filter.group == -1 && do_link == 1) { ++ *strchrnul(filter_dev, ':') = '\0'; + if (iplink_get(0, filter_dev, RTEXT_FILTER_VF) < 0) { + perror("Cannot send link get request"); + exit(1); +-- +1.8.3.1 + diff --git a/SPECS/iproute.spec b/SPECS/iproute.spec index 0521a43..0f0a78e 100644 --- a/SPECS/iproute.spec +++ b/SPECS/iproute.spec @@ -2,7 +2,7 @@ %define rpmversion 4.11.0 %define baserelease 0.el7 -%define specrelease 14%{?dist} +%define specrelease 14%{?dist}.2 %define pkg_release %{specrelease}%{?buildid} Summary: Advanced IP routing and network device configuration tools @@ -58,6 +58,11 @@ Patch39: 0040-link_gre6-Detect-invalid-encaplimit-values.patch Patch40: 0041-man-tc-csum.8-Fix-inconsistency-in-example-descripti.patch Patch41: 0042-tc-fix-command-tc-actions-del-hang-issue.patch Patch42: 0043-ip-link-Fix-use-after-free-in-nl_get_ll_addr_len.patch +Patch43: 0050-iproute-Abort-if-nexthop-cannot-be-parsed.patch +Patch44: 0051-ip-route-Fix-segfault-with-many-nexthops.patch +Patch45: 0052-man-ip-route.8-Document-nexthop-limit.patch +Patch46: 0053-ip-route-Fix-nexthop-encap-parsing.patch +Patch47: 0054-ip-link-Fix-listing-of-alias-interfaces.patch License: GPLv2+ and Public Domain BuildRequires: bison BuildRequires: flex @@ -170,6 +175,15 @@ cat %{SOURCE3} >>%{buildroot}%{_sysconfdir}/iproute2/rt_dsfield %{_includedir}/iproute2/bpf_elf.h %changelog +* Tue Mar 12 2019 Phil Sutter [4.11.0-14.el7_6.2] +- ip-link: Fix listing of alias interfaces (Phil Sutter) [1687717] + +* Fri Mar 01 2019 Phil Sutter [4.11.0-14.el7_6.1] +- ip-route: Fix nexthop encap parsing (Phil Sutter) [1679996] +- man: ip-route.8: Document nexthop limit (Phil Sutter) [1679996] +- ip-route: Fix segfault with many nexthops (Phil Sutter) [1679996] +- iproute: Abort if nexthop cannot be parsed (Phil Sutter) [1679996] + * Tue Mar 06 2018 Phil Sutter [4.11.0-14.el7] - ip-link: Fix use after free in nl_get_ll_addr_len() (Phil Sutter) [1550097]