Bug#988683: unblock: neutron/17.1.1-5 (CVE-2021-20267)
Package: release.debian.org
Severity: normal
User: release.debian.org@packages.debian.org
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 <zigo@debian.org> 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 <david.sinquin@gandi.net>
+Author: Slawek Kaplonski <skaplons@redhat.com>
+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
Reply to: