Gentoo Archives: gentoo-commits

From: David Seifert <soap@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] repo/gentoo:master commit in: sys-cluster/swift/files/
Date: Thu, 09 Feb 2017 22:38:10
Message-Id: 1486679831.29e972873bc1172272482c7579ac1a0c2ffbad5a.soap@gentoo
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 -