Package: neutron / 2:13.0.2-15

CVE-2019-9735_When_converting_sg_rules_to_iptables_do_not_emit_dport_if_not_supported.patch Patch series | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
Description: CVE-2019-9735: When converting sg rules to iptables, do not emit dport if not supported
 Since iptables-restore doesn't support --dport with protocol vrrp,
 it errors out setting the security groups on the hypervisor.
 .
 Marking this a partial fix, since we need a change to prevent
 adding those incompatible rules in the first place, but this
 patch will stop the bleeding.
From: Doug Wiegley <dwiegley@salesforce.com>
Date: Sat, 2 Mar 2019 22:35:52 -0700
Change-Id: If5e557a8e61c3aa364ba1e2c60be4cbe74c1ec8f
Bug-Debian: https://bugs.debian.org/924508
Bug-Ubuntu: https://bugs.launchpad.net/neutron/+bug/1818385
Origin: upstream, https://review.openstack.org/#/c/640685/
Last-Update: 2019-03-15

diff --git a/neutron/agent/linux/iptables_firewall.py b/neutron/agent/linux/iptables_firewall.py
index 496376d..5fb9740 100644
--- a/neutron/agent/linux/iptables_firewall.py
+++ b/neutron/agent/linux/iptables_firewall.py
@@ -46,6 +46,15 @@ IPSET_DIRECTION = {constants.INGRESS_DIRECTION: 'src',
 comment_rule = iptables_manager.comment_rule
 libc = ctypes.CDLL(util.find_library('libc.so.6'))
 
+# iptables protocols that support --dport and --sport
+IPTABLES_PORT_PROTOCOLS = [
+    constants.PROTO_NAME_DCCP,
+    constants.PROTO_NAME_SCTP,
+    constants.PROTO_NAME_TCP,
+    constants.PROTO_NAME_UDP,
+    constants.PROTO_NAME_UDPLITE
+]
+
 
 def get_hybrid_port_name(port_name):
     return (constants.TAP_DEVICE_PREFIX + port_name)[:n_const.LINUX_DEV_LEN]
@@ -731,11 +740,12 @@ class IptablesFirewallDriver(firewall.FirewallDriver):
             # icmp code can be 0 so we cannot use "if port_range_max" here
             if port_range_max is not None:
                 args[-1] += '/%s' % port_range_max
-        elif port_range_min == port_range_max:
-            args += ['--%s' % direction, '%s' % (port_range_min,)]
-        else:
-            args += ['-m', 'multiport', '--%ss' % direction,
-                     '%s:%s' % (port_range_min, port_range_max)]
+        elif protocol in IPTABLES_PORT_PROTOCOLS:
+            if port_range_min == port_range_max:
+                args += ['--%s' % direction, '%s' % (port_range_min,)]
+            else:
+                args += ['-m', 'multiport', '--%ss' % direction,
+                         '%s:%s' % (port_range_min, port_range_max)]
         return args
 
     def _ip_prefix_arg(self, direction, ip_prefix):
diff --git a/neutron/tests/unit/agent/linux/test_iptables_firewall.py b/neutron/tests/unit/agent/linux/test_iptables_firewall.py
index d7268bc..7ab8a0a 100644
--- a/neutron/tests/unit/agent/linux/test_iptables_firewall.py
+++ b/neutron/tests/unit/agent/linux/test_iptables_firewall.py
@@ -276,6 +276,20 @@ class IptablesFirewallTestCase(BaseIptablesFirewallTestCase):
         egress = None
         self._test_prepare_port_filter(rule, ingress, egress)
 
+    def test_filter_bad_vrrp_with_dport(self):
+        rule = {'ethertype': 'IPv4',
+                'direction': 'ingress',
+                'protocol': 'vrrp',
+                'port_range_min': 10,
+                'port_range_max': 10}
+        # Dest port isn't support with VRRP, so don't send it
+        # down to iptables.
+        ingress = mock.call.add_rule('ifake_dev',
+                                     '-p vrrp -j RETURN',
+                                     top=False, comment=None)
+        egress = None
+        self._test_prepare_port_filter(rule, ingress, egress)
+
     def test_filter_ipv4_ingress_tcp_port_by_num(self):
         rule = {'ethertype': 'IPv4',
                 'direction': 'ingress',
-- 
cgit v1.1