Your message dated Tue, 18 May 2021 09:58:01 +0000
with message-id <[email protected]>
and subject line unblock neutron
has caused the Debian Bug report #988683,
regarding unblock: neutron/17.1.1-5 (CVE-2021-20267)
to be marked as done.

This means that you claim that the problem has been dealt with.
If this is not the case it is now your responsibility to reopen the
Bug report if necessary, and/or fix the problem forthwith.

(NB: If you are a system administrator and have no idea what this
message is talking about, this may indicate a serious mail system
misconfiguration somewhere. Please contact [email protected]
immediately.)


-- 
988683: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=988683
Debian Bug Tracking System
Contact [email protected] with problems
--- Begin Message ---
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

--- End Message ---
--- Begin Message ---
Unblocked.

--- End Message ---

Reply via email to