Skip to content

Commit 9e41114

Browse files
committed
Fix obscure segfault condition in PL/Python
In PLy_output(), when the elog() call in the TRY branch throws an exception (this can happen when a statement timeout kicks in, for example), the PyErr_SetString() call in the CATCH branch can cause a segfault, because the Py_XDECREF(so) call before it releases memory that is still used by the sv variable that PyErr_SetString() uses as argument, because sv points into memory owned by so. Backpatched back to 8.0, where this code was introduced. I also threw in a couple of volatile declarations for variables that are used before and after the TRY. I don't think they caused the crash that I observed, but they could become issues.
1 parent 7d535eb commit 9e41114

File tree

1 file changed

+7
-4
lines changed

1 file changed

+7
-4
lines changed

src/pl/plpython/plpython.c

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**********************************************************************
22
* plpython.c - python as a procedural language for PostgreSQL
33
*
4-
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.130 2009/09/13 22:07:06 petere Exp $
4+
* $PostgreSQL: pgsql/src/pl/plpython/plpython.c,v 1.131 2009/11/03 09:35:18 petere Exp $
55
*
66
*********************************************************************
77
*/
@@ -3076,9 +3076,9 @@ PLy_fatal(PyObject *self, PyObject *args)
30763076
static PyObject *
30773077
PLy_output(volatile int level, PyObject *self, PyObject *args)
30783078
{
3079-
PyObject *so;
3079+
PyObject *volatile so;
30803080
char *volatile sv;
3081-
MemoryContext oldcontext;
3081+
volatile MemoryContext oldcontext;
30823082

30833083
so = PyObject_Str(args);
30843084
if (so == NULL || ((sv = PyString_AsString(so)) == NULL))
@@ -3097,14 +3097,17 @@ PLy_output(volatile int level, PyObject *self, PyObject *args)
30973097
MemoryContextSwitchTo(oldcontext);
30983098
PLy_error_in_progress = CopyErrorData();
30993099
FlushErrorState();
3100+
3101+
PyErr_SetString(PLy_exc_error, sv);
3102+
/* Note: If sv came from PyString_AsString(), it points into
3103+
* storage owned by so. So free so after using sv. */
31003104
Py_XDECREF(so);
31013105

31023106
/*
31033107
* returning NULL here causes the python interpreter to bail. when
31043108
* control passes back to PLy_procedure_call, we check for PG
31053109
* exceptions and re-throw the error.
31063110
*/
3107-
PyErr_SetString(PLy_exc_error, sv);
31083111
return NULL;
31093112
}
31103113
PG_END_TRY();

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy