alexk / rpms / rpm

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