[Bug 1493303] Fix merged to swift (stable/liberty)
OpenStack Infra
1493303 at bugs.launchpad.net
Fri Jan 22 03:41:04 UTC 2016
Reviewed: https://review.openstack.org/270235
Committed: https://git.openstack.org/cgit/openstack/swift/commit/?id=8c1976aa771f8c43c5dbe676bd9a5efc69f09eae
Submitter: Jenkins
Branch: stable/liberty
commit 8c1976aa771f8c43c5dbe676bd9a5efc69f09eae
Author: Samuel Merritt <sam at swiftstack.com>
Date: Tue Dec 8 16:36:05 2015 -0800
Fix memory/socket leak in proxy on truncated SLO/DLO GET
When a client disconnected while consuming an SLO or DLO GET response,
the proxy would leak a socket. This could be observed via strace as a
socket that had shutdown() called on it, but was never closed. It
could also be observed by counting entries in /proc/<pid>/fd, where
<pid> is the pid of a proxy server worker process.
This is due to a memory leak in SegmentedIterable. A SegmentedIterable
has an 'app_iter' attribute, which is a generator. That generator
references 'self' (the SegmentedIterable object). This creates a
cyclic reference: the generator refers to the SegmentedIterable, and
the SegmentedIterable refers to the generator.
Python can normally handle cyclic garbage; reference counting won't
reclaim it, but the garbage collector will. However, objects with
finalizers will stop the garbage collector from collecting them* and
the cycle of which they are part.
For most objects, "has finalizer" is synonymous with "has a __del__
method". However, a generator has a finalizer once it's started
running and before it finishes: basically, while it has stack frames
associated with it**.
When a client disconnects mid-stream, we get a memory leak. We have
our SegmentedIterable object (call it "si"), and its associated
generator. si.app_iter is the generator, and the generator closes over
si, so we have a cycle; and the generator has started but not yet
finished, so the generator needs finalization; hence, the garbage
collector won't ever clean it up.
The socket leak comes in because the generator *also* refers to the
request's WSGI environment, which contains wsgi.input, which
ultimately refers to a _socket object from the standard
library. Python's _socket objects only close their underlying file
descriptor when their reference counts fall to 0***.
This commit makes SegmentedIterable.close() call
self.app_iter.close(), thereby unwinding its generator's stack and
making it eligible for garbage collection.
* in Python < 3.4, at least. See PEP 442.
** see PyGen_NeedsFinalizing() in Objects/genobject.c and also
has_finalizer() in Modules/gcmodule.c in Python.
*** see sock_dealloc() in Modules/socketmodule.c in Python. See
sock_close() in the same file for the other half of the sad story.
This closes CVE-2016-0738.
Closes-Bug: 1493303
Change-Id: I74ea49eaa7d5c372cdc2399148d5495d3007dbd0
Co-Authored-By: Kota Tsuyuzaki <tsuyuzaki.kota at lab.ntt.co.jp>
** Changed in: swift
Status: Confirmed => Fix Released
--
You received this bug notification because you are a member of Ubuntu
Server Team, which is subscribed to swift in Ubuntu.
https://bugs.launchpad.net/bugs/1493303
Title:
[OSSA 2016-004] Swift proxy memory leak on unfinished read
(CVE-2016-0738)
To manage notifications about this bug go to:
https://bugs.launchpad.net/cloud-archive/+bug/1493303/+subscriptions
More information about the Ubuntu-server-bugs
mailing list