1 |
commit: 29e972873bc1172272482c7579ac1a0c2ffbad5a |
2 |
Author: Michael Mair-Keimberger (asterix) <m.mairkeimberger <AT> gmail <DOT> com> |
3 |
AuthorDate: Tue Feb 7 16:43:42 2017 +0000 |
4 |
Commit: David Seifert <soap <AT> gentoo <DOT> org> |
5 |
CommitDate: Thu Feb 9 22:37:11 2017 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=29e97287 |
7 |
|
8 |
sys-cluster/swift: remove unused patch |
9 |
|
10 |
Closes: https://github.com/gentoo/gentoo/pull/3870 |
11 |
|
12 |
.../swift/files/cve-2016-0738-stable-liberty.patch | 167 --------------------- |
13 |
1 file changed, 167 deletions(-) |
14 |
|
15 |
diff --git a/sys-cluster/swift/files/cve-2016-0738-stable-liberty.patch b/sys-cluster/swift/files/cve-2016-0738-stable-liberty.patch |
16 |
deleted file mode 100644 |
17 |
index 4d2ccbaa52..0000000000 |
18 |
--- a/sys-cluster/swift/files/cve-2016-0738-stable-liberty.patch |
19 |
+++ /dev/null |
20 |
@@ -1,167 +0,0 @@ |
21 |
-From fc1376b356894f39dfab1e71c1fcb87a943461aa Mon Sep 17 00:00:00 2001 |
22 |
-From: Samuel Merritt <sam@××××××××××.com> |
23 |
-Date: Tue, 8 Dec 2015 16:36:05 -0800 |
24 |
-Subject: [PATCH] Fix memory/socket leak in proxy on truncated SLO/DLO GET |
25 |
- |
26 |
-When a client disconnected while consuming an SLO or DLO GET response, |
27 |
-the proxy would leak a socket. This could be observed via strace as a |
28 |
-socket that had shutdown() called on it, but was never closed. It |
29 |
-could also be observed by counting entries in /proc/<pid>/fd, where |
30 |
-<pid> is the pid of a proxy server worker process. |
31 |
- |
32 |
-This is due to a memory leak in SegmentedIterable. A SegmentedIterable |
33 |
-has an 'app_iter' attribute, which is a generator. That generator |
34 |
-references 'self' (the SegmentedIterable object). This creates a |
35 |
-cyclic reference: the generator refers to the SegmentedIterable, and |
36 |
-the SegmentedIterable refers to the generator. |
37 |
- |
38 |
-Python can normally handle cyclic garbage; reference counting won't |
39 |
-reclaim it, but the garbage collector will. However, objects with |
40 |
-finalizers will stop the garbage collector from collecting them* and |
41 |
-the cycle of which they are part. |
42 |
- |
43 |
-For most objects, "has finalizer" is synonymous with "has a __del__ |
44 |
-method". However, a generator has a finalizer once it's started |
45 |
-running and before it finishes: basically, while it has stack frames |
46 |
-associated with it**. |
47 |
- |
48 |
-When a client disconnects mid-stream, we get a memory leak. We have |
49 |
-our SegmentedIterable object (call it "si"), and its associated |
50 |
-generator. si.app_iter is the generator, and the generator closes over |
51 |
-si, so we have a cycle; and the generator has started but not yet |
52 |
-finished, so the generator needs finalization; hence, the garbage |
53 |
-collector won't ever clean it up. |
54 |
- |
55 |
-The socket leak comes in because the generator *also* refers to the |
56 |
-request's WSGI environment, which contains wsgi.input, which |
57 |
-ultimately refers to a _socket object from the standard |
58 |
-library. Python's _socket objects only close their underlying file |
59 |
-descriptor when their reference counts fall to 0***. |
60 |
- |
61 |
-This commit makes SegmentedIterable.close() call |
62 |
-self.app_iter.close(), thereby unwinding its generator's stack and |
63 |
-making it eligible for garbage collection. |
64 |
- |
65 |
-* in Python < 3.4, at least. See PEP 442. |
66 |
- |
67 |
-** see PyGen_NeedsFinalizing() in Objects/genobject.c and also |
68 |
- has_finalizer() in Modules/gcmodule.c in Python. |
69 |
- |
70 |
-*** see sock_dealloc() in Modules/socketmodule.c in Python. See |
71 |
- sock_close() in the same file for the other half of the sad story. |
72 |
- |
73 |
-Change-Id: I74ea49eaa7d5c372cdc2399148d5495d3007dbd0 |
74 |
-Co-Authored-By: Kota Tsuyuzaki <tsuyuzaki.kota@××××××××××.jp> |
75 |
---- |
76 |
- swift/common/request_helpers.py | 6 ++- |
77 |
- test/unit/common/middleware/test_slo.py | 65 ++++++++++++++++++++++++++++++++- |
78 |
- 2 files changed, 68 insertions(+), 3 deletions(-) |
79 |
- |
80 |
-diff --git a/swift/common/request_helpers.py b/swift/common/request_helpers.py |
81 |
-index a533087..922240a 100644 |
82 |
---- a/swift/common/request_helpers.py |
83 |
-+++ b/swift/common/request_helpers.py |
84 |
-@@ -435,6 +435,9 @@ class SegmentedIterable(object): |
85 |
- self.logger.exception(_('ERROR: An error occurred ' |
86 |
- 'while retrieving segments')) |
87 |
- raise |
88 |
-+ finally: |
89 |
-+ if self.current_resp: |
90 |
-+ close_if_possible(self.current_resp.app_iter) |
91 |
- |
92 |
- def app_iter_range(self, *a, **kw): |
93 |
- """ |
94 |
-@@ -477,5 +480,4 @@ class SegmentedIterable(object): |
95 |
- Called when the client disconnect. Ensure that the connection to the |
96 |
- backend server is closed. |
97 |
- """ |
98 |
-- if self.current_resp: |
99 |
-- close_if_possible(self.current_resp.app_iter) |
100 |
-+ close_if_possible(self.app_iter) |
101 |
-diff --git a/test/unit/common/middleware/test_slo.py b/test/unit/common/middleware/test_slo.py |
102 |
-index b131240..ee0ce0f 100644 |
103 |
---- a/test/unit/common/middleware/test_slo.py |
104 |
-+++ b/test/unit/common/middleware/test_slo.py |
105 |
-@@ -26,7 +26,8 @@ from swift.common import swob, utils |
106 |
- from swift.common.exceptions import ListingIterError, SegmentError |
107 |
- from swift.common.middleware import slo |
108 |
- from swift.common.swob import Request, Response, HTTPException |
109 |
--from swift.common.utils import quote, json, closing_if_possible |
110 |
-+from swift.common.utils import quote, json, closing_if_possible, \ |
111 |
-+ close_if_possible |
112 |
- from test.unit.common.middleware.helpers import FakeSwift |
113 |
- |
114 |
- |
115 |
-@@ -1765,6 +1766,68 @@ class TestSloGetManifest(SloTestCase): |
116 |
- self.assertEqual(headers['X-Object-Meta-Fish'], 'Bass') |
117 |
- self.assertEqual(body, '') |
118 |
- |
119 |
-+ def test_generator_closure(self): |
120 |
-+ # Test that the SLO WSGI iterable closes its internal .app_iter when |
121 |
-+ # it receives a close() message. |
122 |
-+ # |
123 |
-+ # This is sufficient to fix a memory leak. The memory leak arises |
124 |
-+ # due to cyclic references involving a running generator; a running |
125 |
-+ # generator sometimes preventes the GC from collecting it in the |
126 |
-+ # same way that an object with a defined __del__ does. |
127 |
-+ # |
128 |
-+ # There are other ways to break the cycle and fix the memory leak as |
129 |
-+ # well; calling .close() on the generator is sufficient, but not |
130 |
-+ # necessary. However, having this test is better than nothing for |
131 |
-+ # preventing regressions. |
132 |
-+ leaks = [0] |
133 |
-+ |
134 |
-+ class LeakTracker(object): |
135 |
-+ def __init__(self, inner_iter): |
136 |
-+ leaks[0] += 1 |
137 |
-+ self.inner_iter = iter(inner_iter) |
138 |
-+ |
139 |
-+ def __iter__(self): |
140 |
-+ return self |
141 |
-+ |
142 |
-+ def next(self): |
143 |
-+ return next(self.inner_iter) |
144 |
-+ |
145 |
-+ def close(self): |
146 |
-+ leaks[0] -= 1 |
147 |
-+ close_if_possible(self.inner_iter) |
148 |
-+ |
149 |
-+ class LeakTrackingSegmentedIterable(slo.SegmentedIterable): |
150 |
-+ def _internal_iter(self, *a, **kw): |
151 |
-+ it = super( |
152 |
-+ LeakTrackingSegmentedIterable, self)._internal_iter( |
153 |
-+ *a, **kw) |
154 |
-+ return LeakTracker(it) |
155 |
-+ |
156 |
-+ status = [None] |
157 |
-+ headers = [None] |
158 |
-+ |
159 |
-+ def start_response(s, h, ei=None): |
160 |
-+ status[0] = s |
161 |
-+ headers[0] = h |
162 |
-+ |
163 |
-+ req = Request.blank( |
164 |
-+ '/v1/AUTH_test/gettest/manifest-abcd', |
165 |
-+ environ={'REQUEST_METHOD': 'GET', |
166 |
-+ 'HTTP_ACCEPT': 'application/json'}) |
167 |
-+ |
168 |
-+ # can't self.call_slo() here since we don't want to consume the |
169 |
-+ # whole body |
170 |
-+ with patch.object(slo, 'SegmentedIterable', |
171 |
-+ LeakTrackingSegmentedIterable): |
172 |
-+ app_resp = self.slo(req.environ, start_response) |
173 |
-+ self.assertEqual(status[0], '200 OK') # sanity check |
174 |
-+ body_iter = iter(app_resp) |
175 |
-+ chunk = next(body_iter) |
176 |
-+ self.assertEqual(chunk, 'aaaaa') # sanity check |
177 |
-+ |
178 |
-+ app_resp.close() |
179 |
-+ self.assertEqual(0, leaks[0]) |
180 |
-+ |
181 |
- def test_head_manifest_is_efficient(self): |
182 |
- req = Request.blank( |
183 |
- '/v1/AUTH_test/gettest/manifest-abcd', |
184 |
--- |
185 |
-2.7.0 |
186 |
- |
187 |
- |