New submission from Charles-François Natali:
After optimizing epoll() to use a per-instance buffer like poll() does
(http://bugs.python.org/issue16876), I realized that it wasn't thread-safe, and
can result in crashes:
"""
./python /tmp/test.py
*** glibc detected *** ./python: free(): corrupted unsorted chunks:
0x0000000001c8e690 ***
======= Backtrace: =========
/lib64/libc.so.6[0x3041c75676]
./python[0x4fd9ae]
./python(PyThreadState_DeleteCurrent+0x10c)[0x4fdb91]
./python[0x52a444]
/lib64/libpthread.so.0[0x30428077e1]
/lib64/libc.so.6(clone+0x6d)[0x3041ce153d]
======= Memory map: ========
[...]
"""
The problem is that poll (and now epoll) array is stored per-instance, and if
second call to poll() is made while another thread is currently blocked on
poll(), the array is reallocated (through PyMem_Resize()) if the buffer size
has changed (if the number of FDs registered has changed).
"""
static int
update_ufd_array(pollObject *self)
[...]
self->ufd_len = PyDict_Size(self->dict);
PyMem_RESIZE(self->ufds, struct pollfd, self->ufd_len);
[...]
"""
can be called while another thread is blocked there:
"""
/* call poll() */
Py_BEGIN_ALLOW_THREADS
poll_result = poll(self->ufds, self->ufd_len, timeout);
Py_END_ALLOW_THREADS
"""
So when the first call to poll() returns, it can end up in SIGSEGV or heap
corruption (unless the array was increased an realloc() was able to expand it
in-place).
Reproducer script attached.
----------
components: Extension Modules
files: test.py
messages: 179647
nosy: christian.heimes, neologix
priority: normal
severity: normal
stage: needs patch
status: open
title: poll()/epoll() are not thread-safe
type: crash
versions: Python 2.7, Python 3.2, Python 3.3, Python 3.4
Added file: http://bugs.python.org/file28685/test.py
_______________________________________
Python tracker <[email protected]>
<http://bugs.python.org/issue16929>
_______________________________________
_______________________________________________
Python-bugs-list mailing list
Unsubscribe:
http://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com