Subject: | dbh/ SV leak in pg_warn |
The pg_warn-function creates two 'RV wrappers' for accessing a database
handle passed as argument in a way which causes the reference count of
this handle to be incremented twice. Only the second of these is marked
as mortal, causing the database handle (and likely, the first RV wrapper)
to be leaked should the notification processing routine ever actually
be invoked and the last 'user reference' to the dbh go away afterwards,
while the perl interpreter which executed the corresponding code continues
to run (eg, because of mod_perl).
The attached file contains a patch fixing this by creating a single,
mortal RV wrapper and using that in both places.
Subject: | p.txt |
Index: DBD-Pg/dbdimp.c
===================================================================
RCS file: /sysdata/cvs/DBD-Pg/dbdimp.c,v
retrieving revision 1.1.1.2
retrieving revision 1.4.2.1
diff -u -r1.1.1.2 -r1.4.2.1
--- DBD-Pg/dbdimp.c 16 Apr 2009 16:13:18 -0000 1.1.1.2
+++ DBD-Pg/dbdimp.c 20 Apr 2009 15:49:03 -0000 1.4.2.1
@@ -277,6 +277,9 @@
static void pg_warn (void * arg, const char * message)
{
dTHX;
+ SV *tmp;
+
+ tmp = sv_2mortal(newRV((SV *)arg));
/* This fun little bit is to prevent a core dump when the following occurs:
client_min_messages is set to DEBUG3 or greater, and we exit without a disconnect.
@@ -289,11 +292,11 @@
like DBIc_WARN. There may be a better way of handling all this, and we may want to
default to always warn() - input welcome.
*/
- if (!SvROK(SvMAGIC(SvRV(newRV((SV*)arg)))->mg_obj)) {
+ if (!SvROK(SvMAGIC(SvRV(tmp))->mg_obj)) {
return;
}
else {
- D_imp_dbh( sv_2mortal(newRV((SV*)arg)) );
+ D_imp_dbh(tmp);
if (TSTART) TRC(DBILOGFP, "%sBegin pg_warn (message: %s DBIc_WARN: %d PrintWarn: %d)\n",
THEADER,