Package: swift Version: 2.5.0-2 Severity: important Tags: security https://github.com/openstack/swift/commit/8c1976aa771f8c43c5dbe676bd9a5efc69f09eae
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. -- System Information: Debian Release: stretch/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: amd64 (x86_64) Kernel: Linux 4.3.0-1-amd64 (SMP w/1 CPU core) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) Versions of packages swift depends on: ii python-swift 2.5.0-2 pn python:any <none> swift recommends no packages. swift suggests no packages. -- no debconf information _______________________________________________ Secure-testing-team mailing list Secure-testing-team@lists.alioth.debian.org http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/secure-testing-team