[issue16929] poll()/epoll() are not thread-safe

Charles-François Natali report at bugs.python.org
Fri Jan 11 09:36:44 CET 2013


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 <report at bugs.python.org>
<http://bugs.python.org/issue16929>
_______________________________________


More information about the Python-bugs-list mailing list