prometheanfire 15/07/02 05:43:05
Added: cve-2015-3221_2015.1.0.patch
cve-2015-3221_2014.2.3.ebuild
Log:
fixing CVE-2015-3221 no badness remaining
(Portage version: 2.2.18/cvs/Linux x86_64, signed Manifest commit with key
0x33ED3FD25AFC78BA)
Revision Changes Path
1.1 sys-cluster/neutron/files/cve-2015-3221_2015.1.0.patch
file :
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/neutron/files/cve-2015-3221_2015.1.0.patch?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/neutron/files/cve-2015-3221_2015.1.0.patch?rev=1.1&content-type=text/plain
Index: cve-2015-3221_2015.1.0.patch
===================================================================
>From e0c8cbc5dd610b4c580935ea56436495a6d4eb26 Mon Sep 17 00:00:00 2001
From: Aaron Rosen <[email protected]>
Date: Wed, 3 Jun 2015 16:19:39 -0700
Subject: [PATCH] Provide work around for 0.0.0.0/0 ::/0 for ipset
Previously, the ipset_manager would pass in 0.0.0.0/0 or ::/0 if
these addresses were inputted as allowed address pairs. This causes
ipset to raise an error as it does not work with zero prefix sizes.
To solve this problem we use two ipset rules to represent this:
Ipv4: 0.0.0.0/1 and 128.0.0.1/1
IPv6: ::/1' and '8000::/1
All of this logic is handled via _sanitize_addresses() in the ipset_manager
which is called to convert the input.
Closes-bug: 1461054
Conflicts:
neutron/agent/linux/ipset_manager.py
neutron/tests/unit/agent/linux/test_ipset_manager.py
(cherry picked from commit 80a0fc3ba063e036b76e05e89b0cc54fc2d47c81)
---
neutron/agent/linux/ipset_manager.py | 23 ++++++++++++++++++++++
.../tests/unit/agent/linux/test_ipset_manager.py | 19 +++++++++++++++---
2 files changed, 39 insertions(+), 3 deletions(-)
diff --git a/neutron/agent/linux/ipset_manager.py
b/neutron/agent/linux/ipset_manager.py
index 0f76418..af59f1f 100644
--- a/neutron/agent/linux/ipset_manager.py
+++ b/neutron/agent/linux/ipset_manager.py
@@ -11,6 +11,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+import netaddr
+
from neutron.agent.linux import utils as linux_utils
from neutron.common import utils
@@ -31,6 +33,26 @@ class IpsetManager(object):
self.namespace = namespace
self.ipset_sets = {}
+ def _sanitize_addresses(self, addresses):
+ """This method converts any address to ipset format.
+
+ If an address has a mask of /0 we need to cover to it to a mask of
+ /1 as ipset does not support /0 length addresses. Instead we use two
+ /1's to represent the /0.
+ """
+ sanitized_addresses = []
+ for ip in addresses:
+ if (netaddr.IPNetwork(ip).prefixlen == 0):
+ if(netaddr.IPNetwork(ip).version == 4):
+ sanitized_addresses.append('0.0.0.0/1')
+ sanitized_addresses.append('128.0.0.0/1')
+ elif (netaddr.IPNetwork(ip).version == 6):
+ sanitized_addresses.append('::/1')
+ sanitized_addresses.append('8000::/1')
+ else:
+ sanitized_addresses.append(ip)
+ return sanitized_addresses
+
@staticmethod
def get_name(id, ethertype):
"""Returns the given ipset name for an id+ethertype pair.
@@ -51,6 +73,7 @@ class IpsetManager(object):
add / remove new members, or swapped atomically if
that's faster.
"""
+ member_ips = self._sanitize_addresses(member_ips)
set_name = self.get_name(id, ethertype)
if not self.set_exists(id, ethertype):
# The initial creation is handled with create/refresh to
diff --git a/neutron/tests/unit/agent/linux/test_ipset_manager.py
b/neutron/tests/unit/agent/linux/test_ipset_manager.py
index 4484008..a1c6dc5 100644
--- a/neutron/tests/unit/agent/linux/test_ipset_manager.py
+++ b/neutron/tests/unit/agent/linux/test_ipset_manager.py
@@ -38,7 +38,7 @@ class BaseIpsetManagerTest(base.BaseTestCase):
def expect_set(self, addresses):
temp_input = ['create NETIPv4fake_sgid-new hash:net family inet']
temp_input.extend('add NETIPv4fake_sgid-new %s' % ip
- for ip in addresses)
+ for ip in self.ipset._sanitize_addresses(addresses))
input = '\n'.join(temp_input)
self.expected_calls.extend([
mock.call(['ipset', 'restore', '-exist'],
@@ -55,13 +55,16 @@ class BaseIpsetManagerTest(base.BaseTestCase):
self.expected_calls.extend(
mock.call(['ipset', 'add', '-exist', TEST_SET_NAME, ip],
process_input=None,
- run_as_root=True) for ip in addresses)
+ run_as_root=True)
+ for ip in self.ipset._sanitize_addresses(addresses))
def expect_del(self, addresses):
+
self.expected_calls.extend(
mock.call(['ipset', 'del', TEST_SET_NAME, ip],
process_input=None,
- run_as_root=True) for ip in addresses)
+ run_as_root=True)
+ for ip in self.ipset._sanitize_addresses(addresses))
def expect_create(self):
self.expected_calls.append(
@@ -113,6 +116,16 @@ class IpsetManagerTestCase(BaseIpsetManagerTest):
self.ipset.set_members(TEST_SET_ID, ETHERTYPE, FAKE_IPS)
self.verify_mock_calls()
+ def test_set_members_adding_all_zero_ipv4(self):
+ self.expect_set(['0.0.0.0/0'])
+ self.ipset.set_members(TEST_SET_ID, ETHERTYPE, ['0.0.0.0/0'])
+ self.verify_mock_calls()
+
+ def test_set_members_adding_all_zero_ipv6(self):
+ self.expect_set(['::/0'])
+ self.ipset.set_members(TEST_SET_ID, ETHERTYPE, ['::/0'])
+ self.verify_mock_calls()
+
def test_destroy(self):
self.add_first_ip()
self.expect_destroy()
--
1.9.1
1.1 sys-cluster/neutron/files/cve-2015-3221_2014.2.3.ebuild
file :
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/neutron/files/cve-2015-3221_2014.2.3.ebuild?rev=1.1&view=markup
plain:
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/sys-cluster/neutron/files/cve-2015-3221_2014.2.3.ebuild?rev=1.1&content-type=text/plain
Index: cve-2015-3221_2014.2.3.ebuild
===================================================================
>From ac8fb28a920c7a6284d41f7cce054ea1b2e73cb1 Mon Sep 17 00:00:00 2001
From: Aaron Rosen <[email protected]>
Date: Thu, 11 Jun 2015 13:58:16 -0700
Subject: [PATCH] Disable allowed_address_pair ip 0.0.0.0/0 ::/0 for ipset
Previously, the ipset_manager would pass in 0.0.0.0/0 or ::/0 if
these addresses were inputted as allowed address pairs. This causes
ipset to raise an error as it does not work with zero prefix sizes.
To solve this problem we use two ipset rules to represent this.
This was correctly fixed in a backport to kilo though we did not have the
cycles to backport this exact fix to juno as in juno additional work needs to
be done because the iptable and ipset code are interleaved together. This
patch fixes this issue by disabling one from creating an address pair of
zero lenght. This patch also provides a small tool which one should run:
tools/fix_zero_length_ip_prefix.py which changes all zero length address_pair
rules into two address pair rules of:
Ipv4: 0.0.0.0/1 and 128.0.0.1/1
IPv6: ::/1' and '8000::/1
to avoid the problem.
After this patch is merged into juno it will be easier for us to apply
a better change to allow /0 addresses again in juno.
Closes-bug: 1461054
Co-Authored-by: Darragh O'Reilly <[email protected]>
---
neutron/extensions/allowedaddresspairs.py | 9 +++-
.../unit/test_extension_allowedaddresspairs.py | 5 ++
tools/fix_zero_length_ip_prefix.py | 59 ++++++++++++++++++++++
3 files changed, 72 insertions(+), 1 deletion(-)
create mode 100755 tools/fix_zero_length_ip_prefix.py
diff --git a/neutron/extensions/allowedaddresspairs.py
b/neutron/extensions/allowedaddresspairs.py
index 6588d5f..a773a17 100644
--- a/neutron/extensions/allowedaddresspairs.py
+++ b/neutron/extensions/allowedaddresspairs.py
@@ -12,6 +12,7 @@
# License for the specific language governing permissions and limitations
# under the License.
+import netaddr
import webob.exc
from neutron.api.v2 import attributes as attr
@@ -46,6 +47,10 @@ class AllowedAddressPairExhausted(nexception.BadRequest):
"exceeds the maximum %(quota)s.")
+class AllowedAddressPairsZeroPrefixNotAllowed(nexception.InvalidInput):
+ message = _("AllowedAddressPair CIDR cannot have prefix length zero")
+
+
def _validate_allowed_address_pairs(address_pairs, valid_values=None):
unique_check = {}
if len(address_pairs) > cfg.CONF.max_allowed_address_pair:
@@ -77,7 +82,9 @@ def _validate_allowed_address_pairs(address_pairs,
valid_values=None):
set(['mac_address', 'ip_address'])))
raise webob.exc.HTTPBadRequest(msg)
- if '/' in ip_address:
+ if (netaddr.IPNetwork(ip_address).prefixlen == 0):
+ raise AllowedAddressPairsZeroPrefixNotAllowed()
+ elif '/' in ip_address:
msg = attr._validate_subnet(ip_address)
else:
msg = attr._validate_ip_address(ip_address)
diff --git a/neutron/tests/unit/test_extension_allowedaddresspairs.py
b/neutron/tests/unit/test_extension_allowedaddresspairs.py
index bcaa11b..f15c402 100644
--- a/neutron/tests/unit/test_extension_allowedaddresspairs.py
+++ b/neutron/tests/unit/test_extension_allowedaddresspairs.py
@@ -140,6 +140,11 @@ class
TestAllowedAddressPairs(AllowedAddressPairDBTestCase):
self.deserialize(self.fmt, res)
self.assertEqual(res.status_int, 409)
+ def test_create_port_zero_prefix_ip(self):
+ address_pairs = [{'mac_address': 'invalid_mac',
+ 'ip_address': '0.0.0.0/0'}]
+ self._create_port_with_address_pairs(address_pairs, 400)
+
def test_create_port_bad_mac(self):
address_pairs = [{'mac_address': 'invalid_mac',
'ip_address': '10.0.0.1'}]
diff --git a/tools/fix_zero_length_ip_prefix.py
b/tools/fix_zero_length_ip_prefix.py
new file mode 100755
index 0000000..dbbafb5
--- /dev/null
+++ b/tools/fix_zero_length_ip_prefix.py
@@ -0,0 +1,59 @@
+"""
+This script is needed to convert addresses that are zero prefix to be two
+address of one prefix to avoid a bug that exists in juno where the ipset
+manager isn't able to handle zero prefix lenght addresses.
+"""
+
+import os
+import sys
+
+import netaddr
+from neutronclient.v2_0 import client
+
+
+def main():
+ try:
+ username = os.environ['OS_USERNAME']
+ tenant_name = os.environ['OS_TENANT_NAME']
+ password = os.environ['OS_PASSWORD']
+ auth_url = os.environ['OS_AUTH_URL']
+ except KeyError:
+ print("You need to source your openstack creds file first!")
+ sys.exit(1)
+
+ neutron = client.Client(username=username,
+ tenant_name=tenant_name,
+ password=password,
+ auth_url=auth_url)
+
+ ports = neutron.list_ports()
+ for port in ports['ports']:
+ new_address_pairs = []
+ needs_update = False
+ allowed_address_pairs = port.get('allowed_address_pairs')
+ if allowed_address_pairs:
+ for address_pair in allowed_address_pairs:
+ ip = address_pair['ip_address']
+ mac = address_pair['mac_address']
+ if(netaddr.IPNetwork(ip).prefixlen == 0):
+ needs_update = True
+ if(netaddr.IPNetwork(ip).version == 4):
+ new_address_pairs.append({'ip_address': '0.0.0.0/1',
+ 'mac_address': mac})
+ new_address_pairs.append({'ip_address': '128.0.0.0/1',
+ 'mac_address': mac})
+ elif(netaddr.IPNetwork(ip).version == 6):
+ new_address_pairs.append({'ip_address': '::/1',
+ 'mac_address': mac})
+ new_address_pairs.append({'ip_address': '8000::/1',
+ 'mac_address': mac})
+ else:
+ new_address_pairs.append(address_pair)
+ if needs_update:
+ print ("Updating port %s with new address_pairs %s" %
+ (port['id'], new_address_pairs))
+ neutron.update_port(
+ port['id'],
+ {'port': {'allowed_address_pairs': new_address_pairs}})
+
+main()
--
1.9.1