Package: release.debian.org Severity: normal User: [email protected] Usertags: unblock
Please unblock package neutron [ Reason ] Fixing CVE-2021-20267 [ Impact ] If the patch isn't applied, cloud users can spoof IPv6 addrs. [ Tests ] Upstream has an extensive CI, doing both unit and functional tests, so I'm confident it's safe. [ Risks ] This deals with OVS, so one got to understand the internals of OVS to understand it. [ Checklist ] [x] all changes are documented in the d/changelog [x] I reviewed all changes and I approve them [x] attach debdiff against the package in testing [ Other info ] unblock neutron/17.1.1-5 Cheers, Thomas Goirand (zigo)
diff -Nru neutron-17.1.1/debian/changelog neutron-17.1.1/debian/changelog --- neutron-17.1.1/debian/changelog 2021-04-21 17:26:26.000000000 +0200 +++ neutron-17.1.1/debian/changelog 2021-05-17 20:47:34.000000000 +0200 @@ -1,3 +1,11 @@ +neutron (2:17.1.1-5) unstable; urgency=high + + * CVE-2021-20267: Anti-spoofing bypass using Open vSwitch. Applied upstream + patch: Restrict_IPv6_NA_and_DHCPv6_IP_and_MAC_source_addresses.patch + (Closes: #985104). + + -- Thomas Goirand <[email protected]> Mon, 17 May 2021 20:47:34 +0200 + neutron (2:17.1.1-4) unstable; urgency=medium * Restore sanity in ml2_conf.ini / metadata_agent.ini generation (last diff -Nru neutron-17.1.1/debian/patches/CVE-2021-20267_Restrict_IPv6_NA_and_DHCPv6_IP_and_MAC_source_addresses.patch neutron-17.1.1/debian/patches/CVE-2021-20267_Restrict_IPv6_NA_and_DHCPv6_IP_and_MAC_source_addresses.patch --- neutron-17.1.1/debian/patches/CVE-2021-20267_Restrict_IPv6_NA_and_DHCPv6_IP_and_MAC_source_addresses.patch 1970-01-01 01:00:00.000000000 +0100 +++ neutron-17.1.1/debian/patches/CVE-2021-20267_Restrict_IPv6_NA_and_DHCPv6_IP_and_MAC_source_addresses.patch 2021-05-17 20:47:34.000000000 +0200 @@ -0,0 +1,164 @@ +Subject: CVE-2021-20267: Restrict IPv6 NA and DHCP(v6) IP and MAC source addresses + Neighbor Advertisments are used to inform other machines of the MAC + address to use to reach an IPv6. This commits prevents VMs from + pretending they are assigned IPv6 they should not use. + . + It also prevents sending UDP packets with spoofed IP or MAC even using + DHCP(v6) request ports. +Co-authored-by: David Sinquin <[email protected]> +Author: Slawek Kaplonski <[email protected]> +Date: Mon, 29 Mar 2021 22:21:15 +0200 +Closes-bug: #1902917 +Change-Id: Iffb6643359562487414460f5a7e19a7fae9f935c +Origin: https://review.opendev.org/c/openstack/neutron/+/791465 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=985104 +Last-Update: 2021-05-17 + +diff --git a/neutron/agent/firewall.py b/neutron/agent/firewall.py +index f8f6615..62eee30 100644 +--- a/neutron/agent/firewall.py ++++ b/neutron/agent/firewall.py +@@ -34,8 +34,11 @@ + # List of ICMPv6 types that should be permitted (egress) by default. + ICMPV6_ALLOWED_EGRESS_TYPES = (n_const.ICMPV6_TYPE_MLD_QUERY, + n_const.ICMPV6_TYPE_RS, +- n_const.ICMPV6_TYPE_NS, +- n_const.ICMPV6_TYPE_NA) ++ n_const.ICMPV6_TYPE_NS) ++ ++# List of ICMPv6 types that should be permitted depending on payload content ++# to avoid spoofing (egress) by default. ++ICMPV6_RESTRICTED_EGRESS_TYPES = (n_const.ICMPV6_TYPE_NA, ) + + + def port_sec_enabled(port): +diff --git a/neutron/agent/linux/openvswitch_firewall/firewall.py b/neutron/agent/linux/openvswitch_firewall/firewall.py +index 5683b8a..e385a41 100644 +--- a/neutron/agent/linux/openvswitch_firewall/firewall.py ++++ b/neutron/agent/linux/openvswitch_firewall/firewall.py +@@ -910,8 +910,7 @@ + self._initialize_ingress(port) + + def _initialize_egress_ipv6_icmp(self, port, allowed_pairs): +- # NOTE(slaweq): should we include also fe80::/64 (link-local) subnet +- # in the allowed pairs here? ++ allowed_pairs = allowed_pairs.union({(port.mac, port.lla_address)}) + for mac_addr, ip_addr in allowed_pairs: + for icmp_type in firewall.ICMPV6_ALLOWED_EGRESS_TYPES: + self._add_flow( +@@ -927,6 +926,19 @@ + actions='resubmit(,%d)' % ( + ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE) + ) ++ for icmp_type in firewall.ICMPV6_RESTRICTED_EGRESS_TYPES: ++ self._add_flow( ++ table=ovs_consts.BASE_EGRESS_TABLE, ++ priority=95, ++ in_port=port.ofport, ++ reg_port=port.ofport, ++ dl_type=lib_const.ETHERTYPE_IPV6, ++ nw_proto=lib_const.PROTO_NUM_IPV6_ICMP, ++ icmp_type=icmp_type, ++ nd_target=ip_addr, ++ actions='resubmit(,%d)' % ( ++ ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE) ++ ) + + def _initialize_egress_no_port_security(self, port_id, ovs_ports=None): + try: +@@ -1001,9 +1013,9 @@ + """Identify egress traffic and send it to egress base""" + + # Apply mac/ip pairs for IPv4 +- allowed_pairs = port.allowed_pairs_v4.union( ++ allowed_mac_ipv4_pairs = port.allowed_pairs_v4.union( + {(port.mac, ip_addr) for ip_addr in port.ipv4_addresses}) +- for mac_addr, ip_addr in allowed_pairs: ++ for mac_addr, ip_addr in allowed_mac_ipv4_pairs: + self._add_flow( + table=ovs_consts.BASE_EGRESS_TABLE, + priority=95, +@@ -1029,10 +1041,10 @@ + ) + + # Apply mac/ip pairs for IPv6 +- allowed_pairs = port.allowed_pairs_v6.union( ++ allowed_mac_ipv6_pairs = port.allowed_pairs_v6.union( + {(port.mac, ip_addr) for ip_addr in port.ipv6_addresses}) +- self._initialize_egress_ipv6_icmp(port, allowed_pairs) +- for mac_addr, ip_addr in allowed_pairs: ++ self._initialize_egress_ipv6_icmp(port, allowed_mac_ipv6_pairs) ++ for mac_addr, ip_addr in allowed_mac_ipv6_pairs: + self._add_flow( + table=ovs_consts.BASE_EGRESS_TABLE, + priority=65, +@@ -1047,21 +1059,30 @@ + ) + + # DHCP discovery +- for dl_type, src_port, dst_port in ( +- (lib_const.ETHERTYPE_IP, 68, 67), +- (lib_const.ETHERTYPE_IPV6, 546, 547)): +- self._add_flow( +- table=ovs_consts.BASE_EGRESS_TABLE, +- priority=80, +- reg_port=port.ofport, +- in_port=port.ofport, +- dl_type=dl_type, +- nw_proto=lib_const.PROTO_NUM_UDP, +- tp_src=src_port, +- tp_dst=dst_port, +- actions='resubmit(,{:d})'.format( +- ovs_consts.ACCEPT_OR_INGRESS_TABLE) +- ) ++ additional_ipv4_filters = [ ++ {"dl_src": mac, "nw_src": ip} ++ for mac, ip in (*allowed_mac_ipv4_pairs, ++ (port.mac, '0.0.0.0'),)] ++ additional_ipv6_filters = [ ++ {"dl_src": mac, "ipv6_src": ip} ++ for mac, ip in allowed_mac_ipv6_pairs] ++ for dl_type, src_port, dst_port, filters_list in ( ++ (lib_const.ETHERTYPE_IP, 68, 67, additional_ipv4_filters), ++ (lib_const.ETHERTYPE_IPV6, 546, 547, additional_ipv6_filters)): ++ for additional_filters in filters_list: ++ self._add_flow( ++ table=ovs_consts.BASE_EGRESS_TABLE, ++ priority=80, ++ reg_port=port.ofport, ++ in_port=port.ofport, ++ dl_type=dl_type, ++ **additional_filters, ++ nw_proto=lib_const.PROTO_NUM_UDP, ++ tp_src=src_port, ++ tp_dst=dst_port, ++ actions='resubmit(,{:d})'.format( ++ ovs_consts.ACCEPT_OR_INGRESS_TABLE) ++ ) + # Ban dhcp service running on an instance + for dl_type, src_port, dst_port in ( + (lib_const.ETHERTYPE_IP, 67, 68), +diff --git a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py +index f674112..8e07e51 100644 +--- a/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py ++++ b/neutron/tests/unit/agent/linux/openvswitch_firewall/test_firewall.py +@@ -1039,6 +1039,19 @@ + ipv6_src='2003::1', + actions='resubmit(,%d)' % ( + ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE))) ++ for icmp_type in agent_firewall.ICMPV6_RESTRICTED_EGRESS_TYPES: ++ expected_calls.append( ++ mock.call( ++ table=ovs_consts.BASE_EGRESS_TABLE, ++ priority=95, ++ in_port=TESTING_VLAN_TAG, ++ reg5=TESTING_VLAN_TAG, ++ dl_type='0x86dd', ++ nw_proto=constants.PROTO_NUM_IPV6_ICMP, ++ icmp_type=icmp_type, ++ nd_target='2003::1', ++ actions='resubmit(,%d)' % ( ++ ovs_consts.ACCEPTED_EGRESS_TRAFFIC_NORMAL_TABLE))) + self.mock_bridge.br.add_flow.assert_has_calls(expected_calls) + + def test_process_trusted_ports_caches_port_id(self): diff -Nru neutron-17.1.1/debian/patches/series neutron-17.1.1/debian/patches/series --- neutron-17.1.1/debian/patches/series 2021-04-21 17:26:26.000000000 +0200 +++ neutron-17.1.1/debian/patches/series 2021-05-17 20:47:34.000000000 +0200 @@ -1 +1,2 @@ Floating_IP_s_for_routed_networks.patch +CVE-2021-20267_Restrict_IPv6_NA_and_DHCPv6_IP_and_MAC_source_addresses.patch

