Skip to content

Commit 93f4118

Browse files
author
Ma Lin
authored
Fix thread locks in zlib module may go wrong in rare case. (#22126)
Setting `next_in` before acquiring the thread lock may mix up compress/decompress state in other threads.
1 parent 878bc8b commit 93f4118

File tree

2 files changed

+11
-9
lines changed

2 files changed

+11
-9
lines changed
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix thread locks in zlib module may go wrong in rare case. Patch by Ma Lin.

Modules/zlibmodule.c

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
#include "zlib.h"
1111

1212

13-
#define ENTER_ZLIB(obj) \
14-
Py_BEGIN_ALLOW_THREADS; \
15-
PyThread_acquire_lock((obj)->lock, 1); \
16-
Py_END_ALLOW_THREADS;
13+
#define ENTER_ZLIB(obj) do { \
14+
if (!PyThread_acquire_lock((obj)->lock, 0)) { \
15+
Py_BEGIN_ALLOW_THREADS \
16+
PyThread_acquire_lock((obj)->lock, 1); \
17+
Py_END_ALLOW_THREADS \
18+
} } while (0)
1719
#define LEAVE_ZLIB(obj) PyThread_release_lock((obj)->lock);
1820

1921
#if defined(ZLIB_VERNUM) && ZLIB_VERNUM >= 0x1221
@@ -634,14 +636,13 @@ zlib_Compress_compress_impl(compobject *self, PyTypeObject *cls,
634636
PyObject *RetVal = NULL;
635637
Py_ssize_t obuflen = DEF_BUF_SIZE;
636638
int err;
637-
638639
zlibstate *state = PyType_GetModuleState(cls);
639640

641+
ENTER_ZLIB(self);
642+
640643
self->zst.next_in = data->buf;
641644
Py_ssize_t ibuflen = data->len;
642645

643-
ENTER_ZLIB(self);
644-
645646
do {
646647
arrange_input_buffer(&self->zst, &ibuflen);
647648

@@ -761,15 +762,15 @@ zlib_Decompress_decompress_impl(compobject *self, PyTypeObject *cls,
761762
else
762763
hard_limit = max_length;
763764

765+
ENTER_ZLIB(self);
766+
764767
self->zst.next_in = data->buf;
765768
ibuflen = data->len;
766769

767770
/* limit amount of data allocated to max_length */
768771
if (max_length && obuflen > max_length)
769772
obuflen = max_length;
770773

771-
ENTER_ZLIB(self);
772-
773774
do {
774775
arrange_input_buffer(&self->zst, &ibuflen);
775776

0 commit comments

Comments
 (0)