1 |
prometheanfire 15/07/02 05:43:05 |
2 |
|
3 |
Added: cve-2015-3221_2015.1.0.patch |
4 |
cve-2015-3221_2014.2.3.ebuild |
5 |
Log: |
6 |
fixing CVE-2015-3221 no badness remaining |
7 |
|
8 |
(Portage version: 2.2.18/cvs/Linux x86_64, signed Manifest commit with key 0x33ED3FD25AFC78BA) |
9 |
|
10 |
Revision Changes Path |
11 |
1.1 sys-cluster/neutron/files/cve-2015-3221_2015.1.0.patch |
12 |
|
13 |
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 |
14 |
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 |
15 |
|
16 |
Index: cve-2015-3221_2015.1.0.patch |
17 |
=================================================================== |
18 |
From e0c8cbc5dd610b4c580935ea56436495a6d4eb26 Mon Sep 17 00:00:00 2001 |
19 |
From: Aaron Rosen <aaronorosen@×××××.com> |
20 |
Date: Wed, 3 Jun 2015 16:19:39 -0700 |
21 |
Subject: [PATCH] Provide work around for 0.0.0.0/0 ::/0 for ipset |
22 |
|
23 |
Previously, the ipset_manager would pass in 0.0.0.0/0 or ::/0 if |
24 |
these addresses were inputted as allowed address pairs. This causes |
25 |
ipset to raise an error as it does not work with zero prefix sizes. |
26 |
To solve this problem we use two ipset rules to represent this: |
27 |
|
28 |
Ipv4: 0.0.0.0/1 and 128.0.0.1/1 |
29 |
IPv6: ::/1' and '8000::/1 |
30 |
|
31 |
All of this logic is handled via _sanitize_addresses() in the ipset_manager |
32 |
which is called to convert the input. |
33 |
|
34 |
Closes-bug: 1461054 |
35 |
|
36 |
Conflicts: |
37 |
neutron/agent/linux/ipset_manager.py |
38 |
neutron/tests/unit/agent/linux/test_ipset_manager.py |
39 |
|
40 |
(cherry picked from commit 80a0fc3ba063e036b76e05e89b0cc54fc2d47c81) |
41 |
--- |
42 |
neutron/agent/linux/ipset_manager.py | 23 ++++++++++++++++++++++ |
43 |
.../tests/unit/agent/linux/test_ipset_manager.py | 19 +++++++++++++++--- |
44 |
2 files changed, 39 insertions(+), 3 deletions(-) |
45 |
|
46 |
diff --git a/neutron/agent/linux/ipset_manager.py b/neutron/agent/linux/ipset_manager.py |
47 |
index 0f76418..af59f1f 100644 |
48 |
--- a/neutron/agent/linux/ipset_manager.py |
49 |
+++ b/neutron/agent/linux/ipset_manager.py |
50 |
@@ -11,6 +11,8 @@ |
51 |
# See the License for the specific language governing permissions and |
52 |
# limitations under the License. |
53 |
|
54 |
+import netaddr |
55 |
+ |
56 |
from neutron.agent.linux import utils as linux_utils |
57 |
from neutron.common import utils |
58 |
|
59 |
@@ -31,6 +33,26 @@ class IpsetManager(object): |
60 |
self.namespace = namespace |
61 |
self.ipset_sets = {} |
62 |
|
63 |
+ def _sanitize_addresses(self, addresses): |
64 |
+ """This method converts any address to ipset format. |
65 |
+ |
66 |
+ If an address has a mask of /0 we need to cover to it to a mask of |
67 |
+ /1 as ipset does not support /0 length addresses. Instead we use two |
68 |
+ /1's to represent the /0. |
69 |
+ """ |
70 |
+ sanitized_addresses = [] |
71 |
+ for ip in addresses: |
72 |
+ if (netaddr.IPNetwork(ip).prefixlen == 0): |
73 |
+ if(netaddr.IPNetwork(ip).version == 4): |
74 |
+ sanitized_addresses.append('0.0.0.0/1') |
75 |
+ sanitized_addresses.append('128.0.0.0/1') |
76 |
+ elif (netaddr.IPNetwork(ip).version == 6): |
77 |
+ sanitized_addresses.append('::/1') |
78 |
+ sanitized_addresses.append('8000::/1') |
79 |
+ else: |
80 |
+ sanitized_addresses.append(ip) |
81 |
+ return sanitized_addresses |
82 |
+ |
83 |
@staticmethod |
84 |
def get_name(id, ethertype): |
85 |
"""Returns the given ipset name for an id+ethertype pair. |
86 |
@@ -51,6 +73,7 @@ class IpsetManager(object): |
87 |
add / remove new members, or swapped atomically if |
88 |
that's faster. |
89 |
""" |
90 |
+ member_ips = self._sanitize_addresses(member_ips) |
91 |
set_name = self.get_name(id, ethertype) |
92 |
if not self.set_exists(id, ethertype): |
93 |
# The initial creation is handled with create/refresh to |
94 |
diff --git a/neutron/tests/unit/agent/linux/test_ipset_manager.py b/neutron/tests/unit/agent/linux/test_ipset_manager.py |
95 |
index 4484008..a1c6dc5 100644 |
96 |
--- a/neutron/tests/unit/agent/linux/test_ipset_manager.py |
97 |
+++ b/neutron/tests/unit/agent/linux/test_ipset_manager.py |
98 |
@@ -38,7 +38,7 @@ class BaseIpsetManagerTest(base.BaseTestCase): |
99 |
def expect_set(self, addresses): |
100 |
temp_input = ['create NETIPv4fake_sgid-new hash:net family inet'] |
101 |
temp_input.extend('add NETIPv4fake_sgid-new %s' % ip |
102 |
- for ip in addresses) |
103 |
+ for ip in self.ipset._sanitize_addresses(addresses)) |
104 |
input = '\n'.join(temp_input) |
105 |
self.expected_calls.extend([ |
106 |
mock.call(['ipset', 'restore', '-exist'], |
107 |
@@ -55,13 +55,16 @@ class BaseIpsetManagerTest(base.BaseTestCase): |
108 |
self.expected_calls.extend( |
109 |
mock.call(['ipset', 'add', '-exist', TEST_SET_NAME, ip], |
110 |
process_input=None, |
111 |
- run_as_root=True) for ip in addresses) |
112 |
+ run_as_root=True) |
113 |
+ for ip in self.ipset._sanitize_addresses(addresses)) |
114 |
|
115 |
def expect_del(self, addresses): |
116 |
+ |
117 |
self.expected_calls.extend( |
118 |
mock.call(['ipset', 'del', TEST_SET_NAME, ip], |
119 |
process_input=None, |
120 |
- run_as_root=True) for ip in addresses) |
121 |
+ run_as_root=True) |
122 |
+ for ip in self.ipset._sanitize_addresses(addresses)) |
123 |
|
124 |
def expect_create(self): |
125 |
self.expected_calls.append( |
126 |
@@ -113,6 +116,16 @@ class IpsetManagerTestCase(BaseIpsetManagerTest): |
127 |
self.ipset.set_members(TEST_SET_ID, ETHERTYPE, FAKE_IPS) |
128 |
self.verify_mock_calls() |
129 |
|
130 |
+ def test_set_members_adding_all_zero_ipv4(self): |
131 |
+ self.expect_set(['0.0.0.0/0']) |
132 |
+ self.ipset.set_members(TEST_SET_ID, ETHERTYPE, ['0.0.0.0/0']) |
133 |
+ self.verify_mock_calls() |
134 |
+ |
135 |
+ def test_set_members_adding_all_zero_ipv6(self): |
136 |
+ self.expect_set(['::/0']) |
137 |
+ self.ipset.set_members(TEST_SET_ID, ETHERTYPE, ['::/0']) |
138 |
+ self.verify_mock_calls() |
139 |
+ |
140 |
def test_destroy(self): |
141 |
self.add_first_ip() |
142 |
self.expect_destroy() |
143 |
-- |
144 |
1.9.1 |
145 |
|
146 |
|
147 |
|
148 |
1.1 sys-cluster/neutron/files/cve-2015-3221_2014.2.3.ebuild |
149 |
|
150 |
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 |
151 |
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 |
152 |
|
153 |
Index: cve-2015-3221_2014.2.3.ebuild |
154 |
=================================================================== |
155 |
From ac8fb28a920c7a6284d41f7cce054ea1b2e73cb1 Mon Sep 17 00:00:00 2001 |
156 |
From: Aaron Rosen <aaronorosen@×××××.com> |
157 |
Date: Thu, 11 Jun 2015 13:58:16 -0700 |
158 |
Subject: [PATCH] Disable allowed_address_pair ip 0.0.0.0/0 ::/0 for ipset |
159 |
|
160 |
Previously, the ipset_manager would pass in 0.0.0.0/0 or ::/0 if |
161 |
these addresses were inputted as allowed address pairs. This causes |
162 |
ipset to raise an error as it does not work with zero prefix sizes. |
163 |
To solve this problem we use two ipset rules to represent this. |
164 |
|
165 |
This was correctly fixed in a backport to kilo though we did not have the |
166 |
cycles to backport this exact fix to juno as in juno additional work needs to |
167 |
be done because the iptable and ipset code are interleaved together. This |
168 |
patch fixes this issue by disabling one from creating an address pair of |
169 |
zero lenght. This patch also provides a small tool which one should run: |
170 |
tools/fix_zero_length_ip_prefix.py which changes all zero length address_pair |
171 |
rules into two address pair rules of: |
172 |
|
173 |
Ipv4: 0.0.0.0/1 and 128.0.0.1/1 |
174 |
IPv6: ::/1' and '8000::/1 |
175 |
|
176 |
to avoid the problem. |
177 |
After this patch is merged into juno it will be easier for us to apply |
178 |
a better change to allow /0 addresses again in juno. |
179 |
|
180 |
Closes-bug: 1461054 |
181 |
Co-Authored-by: Darragh O'Reilly <darragh.oreilly@××.com> |
182 |
--- |
183 |
neutron/extensions/allowedaddresspairs.py | 9 +++- |
184 |
.../unit/test_extension_allowedaddresspairs.py | 5 ++ |
185 |
tools/fix_zero_length_ip_prefix.py | 59 ++++++++++++++++++++++ |
186 |
3 files changed, 72 insertions(+), 1 deletion(-) |
187 |
create mode 100755 tools/fix_zero_length_ip_prefix.py |
188 |
|
189 |
diff --git a/neutron/extensions/allowedaddresspairs.py b/neutron/extensions/allowedaddresspairs.py |
190 |
index 6588d5f..a773a17 100644 |
191 |
--- a/neutron/extensions/allowedaddresspairs.py |
192 |
+++ b/neutron/extensions/allowedaddresspairs.py |
193 |
@@ -12,6 +12,7 @@ |
194 |
# License for the specific language governing permissions and limitations |
195 |
# under the License. |
196 |
|
197 |
+import netaddr |
198 |
import webob.exc |
199 |
|
200 |
from neutron.api.v2 import attributes as attr |
201 |
@@ -46,6 +47,10 @@ class AllowedAddressPairExhausted(nexception.BadRequest): |
202 |
"exceeds the maximum %(quota)s.") |
203 |
|
204 |
|
205 |
+class AllowedAddressPairsZeroPrefixNotAllowed(nexception.InvalidInput): |
206 |
+ message = _("AllowedAddressPair CIDR cannot have prefix length zero") |
207 |
+ |
208 |
+ |
209 |
def _validate_allowed_address_pairs(address_pairs, valid_values=None): |
210 |
unique_check = {} |
211 |
if len(address_pairs) > cfg.CONF.max_allowed_address_pair: |
212 |
@@ -77,7 +82,9 @@ def _validate_allowed_address_pairs(address_pairs, valid_values=None): |
213 |
set(['mac_address', 'ip_address']))) |
214 |
raise webob.exc.HTTPBadRequest(msg) |
215 |
|
216 |
- if '/' in ip_address: |
217 |
+ if (netaddr.IPNetwork(ip_address).prefixlen == 0): |
218 |
+ raise AllowedAddressPairsZeroPrefixNotAllowed() |
219 |
+ elif '/' in ip_address: |
220 |
msg = attr._validate_subnet(ip_address) |
221 |
else: |
222 |
msg = attr._validate_ip_address(ip_address) |
223 |
diff --git a/neutron/tests/unit/test_extension_allowedaddresspairs.py b/neutron/tests/unit/test_extension_allowedaddresspairs.py |
224 |
index bcaa11b..f15c402 100644 |
225 |
--- a/neutron/tests/unit/test_extension_allowedaddresspairs.py |
226 |
+++ b/neutron/tests/unit/test_extension_allowedaddresspairs.py |
227 |
@@ -140,6 +140,11 @@ class TestAllowedAddressPairs(AllowedAddressPairDBTestCase): |
228 |
self.deserialize(self.fmt, res) |
229 |
self.assertEqual(res.status_int, 409) |
230 |
|
231 |
+ def test_create_port_zero_prefix_ip(self): |
232 |
+ address_pairs = [{'mac_address': 'invalid_mac', |
233 |
+ 'ip_address': '0.0.0.0/0'}] |
234 |
+ self._create_port_with_address_pairs(address_pairs, 400) |
235 |
+ |
236 |
def test_create_port_bad_mac(self): |
237 |
address_pairs = [{'mac_address': 'invalid_mac', |
238 |
'ip_address': '10.0.0.1'}] |
239 |
diff --git a/tools/fix_zero_length_ip_prefix.py b/tools/fix_zero_length_ip_prefix.py |
240 |
new file mode 100755 |
241 |
index 0000000..dbbafb5 |
242 |
--- /dev/null |
243 |
+++ b/tools/fix_zero_length_ip_prefix.py |
244 |
@@ -0,0 +1,59 @@ |
245 |
+""" |
246 |
+This script is needed to convert addresses that are zero prefix to be two |
247 |
+address of one prefix to avoid a bug that exists in juno where the ipset |
248 |
+manager isn't able to handle zero prefix lenght addresses. |
249 |
+""" |
250 |
+ |
251 |
+import os |
252 |
+import sys |
253 |
+ |
254 |
+import netaddr |
255 |
+from neutronclient.v2_0 import client |
256 |
+ |
257 |
+ |
258 |
+def main(): |
259 |
+ try: |
260 |
+ username = os.environ['OS_USERNAME'] |
261 |
+ tenant_name = os.environ['OS_TENANT_NAME'] |
262 |
+ password = os.environ['OS_PASSWORD'] |
263 |
+ auth_url = os.environ['OS_AUTH_URL'] |
264 |
+ except KeyError: |
265 |
+ print("You need to source your openstack creds file first!") |
266 |
+ sys.exit(1) |
267 |
+ |
268 |
+ neutron = client.Client(username=username, |
269 |
+ tenant_name=tenant_name, |
270 |
+ password=password, |
271 |
+ auth_url=auth_url) |
272 |
+ |
273 |
+ ports = neutron.list_ports() |
274 |
+ for port in ports['ports']: |
275 |
+ new_address_pairs = [] |
276 |
+ needs_update = False |
277 |
+ allowed_address_pairs = port.get('allowed_address_pairs') |
278 |
+ if allowed_address_pairs: |
279 |
+ for address_pair in allowed_address_pairs: |
280 |
+ ip = address_pair['ip_address'] |
281 |
+ mac = address_pair['mac_address'] |
282 |
+ if(netaddr.IPNetwork(ip).prefixlen == 0): |
283 |
+ needs_update = True |
284 |
+ if(netaddr.IPNetwork(ip).version == 4): |
285 |
+ new_address_pairs.append({'ip_address': '0.0.0.0/1', |
286 |
+ 'mac_address': mac}) |
287 |
+ new_address_pairs.append({'ip_address': '128.0.0.0/1', |
288 |
+ 'mac_address': mac}) |
289 |
+ elif(netaddr.IPNetwork(ip).version == 6): |
290 |
+ new_address_pairs.append({'ip_address': '::/1', |
291 |
+ 'mac_address': mac}) |
292 |
+ new_address_pairs.append({'ip_address': '8000::/1', |
293 |
+ 'mac_address': mac}) |
294 |
+ else: |
295 |
+ new_address_pairs.append(address_pair) |
296 |
+ if needs_update: |
297 |
+ print ("Updating port %s with new address_pairs %s" % |
298 |
+ (port['id'], new_address_pairs)) |
299 |
+ neutron.update_port( |
300 |
+ port['id'], |
301 |
+ {'port': {'allowed_address_pairs': new_address_pairs}}) |
302 |
+ |
303 |
+main() |
304 |
-- |
305 |
1.9.1 |