alexk / rpms / rpm

Forked from rpms/rpm 2 years ago
Clone
0b2921
From 531dc8495cd3aabd3f659ecab604106fdbacbe98 Mon Sep 17 00:00:00 2001
0b2921
Message-Id: <531dc8495cd3aabd3f659ecab604106fdbacbe98.1554974459.git.pmatilai@redhat.com>
0b2921
From: Panu Matilainen <pmatilai@redhat.com>
0b2921
Date: Wed, 3 Oct 2018 11:51:38 +0300
0b2921
Subject: [PATCH] Fix ancient python GIL locking bug on callback
0b2921
 (RhBug:1632488)
0b2921
0b2921
Introduced in commit c7881d801745b4c156a8aa2afc17b95f97481e34 back in 2002,
0b2921
synthesizing a python object for the callback occurs before retaking
0b2921
the GIL lock, which is not allowed. Somehow this has managed to stay
0b2921
latent all these years, and even now requires fairly specific conditions:
0b2921
when the callback gets called without an associated key, such as erasures
0b2921
or file trigger script start/stop events (in the case of RhBug:1632488),
0b2921
when Python 3 is running in PYTHONMALLOC=debug mode,
0b2921
it crashes with "Python memory allocator called without holding the GIL".
0b2921
0b2921
Simply retake the lock before any Python operations take place to fix.
0b2921
---
0b2921
 python/rpmts-py.c | 4 ++--
0b2921
 1 file changed, 2 insertions(+), 2 deletions(-)
0b2921
0b2921
diff --git a/python/rpmts-py.c b/python/rpmts-py.c
0b2921
index e4c5e1250..1ddfc9a1e 100644
0b2921
--- a/python/rpmts-py.c
0b2921
+++ b/python/rpmts-py.c
0b2921
@@ -495,6 +495,8 @@ rpmtsCallback(const void * hd, const rpmCallbackType what,
0b2921
 
0b2921
     if (cbInfo->cb == Py_None) return NULL;
0b2921
 
0b2921
+    PyEval_RestoreThread(cbInfo->_save);
0b2921
+
0b2921
     /* Synthesize a python object for callback (if necessary). */
0b2921
     if (pkgObj == NULL) {
0b2921
 	if (h) {
0b2921
@@ -506,8 +508,6 @@ rpmtsCallback(const void * hd, const rpmCallbackType what,
0b2921
     } else
0b2921
 	Py_INCREF(pkgObj);
0b2921
 
0b2921
-    PyEval_RestoreThread(cbInfo->_save);
0b2921
-
0b2921
     args = Py_BuildValue("(iLLOO)", what, amount, total, pkgObj, cbInfo->data);
0b2921
     result = PyEval_CallObject(cbInfo->cb, args);
0b2921
     Py_DECREF(args);
0b2921
-- 
0b2921
2.20.1
0b2921