minor leaks in pg_dump (PG tarball 10.6)

Started by Pavel Raiskupabout 7 years ago6 messages
#1Pavel Raiskup
praiskup@redhat.com

Among other reports (IMO clearly non-issues), I'm sending patch which
fixes/points to a few resource leaks detected by Coverity that might be
worth fixing. If they are not, feel free to ignore this mail.

Pavel

diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 8a93ace9fa..475d6dbd73 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -95,6 +95,8 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
 	{
 		if (!parsePGArray(racls, &raclitems, &nraclitems))
 		{
+			if (aclitems)
+				free(aclitems);
 			if (raclitems)
 				free(raclitems);
 			return false;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index d583154fba..731a08c15c 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -8284,7 +8284,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
 			res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);

numDefaults = PQntuples(res);
- attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));

for (j = 0; j < numDefaults; j++)
{
@@ -8304,6 +8303,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
if (tbinfo->attisdropped[adnum - 1])
continue;

+				attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
+
 				attrdefs[j].dobj.objType = DO_ATTRDEF;
 				attrdefs[j].dobj.catId.tableoid = atooid(PQgetvalue(res, j, 0));
 				attrdefs[j].dobj.catId.oid = atooid(PQgetvalue(res, j, 1));
@@ -15951,6 +15952,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 								  tbinfo->attfdwoptions[j]);
 			}
 		}
+
+		free(ftoptions);
+		free(srvname);
 	}

/*

#2Stephen Frost
sfrost@snowman.net
In reply to: Pavel Raiskup (#1)
Re: minor leaks in pg_dump (PG tarball 10.6)

Greetings,

* Pavel Raiskup (praiskup@redhat.com) wrote:

Among other reports (IMO clearly non-issues), I'm sending patch which
fixes/points to a few resource leaks detected by Coverity that might be
worth fixing. If they are not, feel free to ignore this mail.

diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 8a93ace9fa..475d6dbd73 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -95,6 +95,8 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
{
if (!parsePGArray(racls, &raclitems, &nraclitems))
{
+			if (aclitems)
+				free(aclitems);
if (raclitems)
free(raclitems);
return false;

Yeah, that could be fixed.

diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index d583154fba..731a08c15c 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -8284,7 +8284,6 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
res = ExecuteSqlQuery(fout, q->data, PGRES_TUPLES_OK);

numDefaults = PQntuples(res);
- attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));

for (j = 0; j < numDefaults; j++)
{
@@ -8304,6 +8303,8 @@ getTableAttrs(Archive *fout, TableInfo *tblinfo, int numTables)
if (tbinfo->attisdropped[adnum - 1])
continue;

+				attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
+

This change doesn't seem to make any sense to me..? If anything, seems
like we'd end up overallocating memory *after* this change, where we
don't today (though an analyzer tool might complain because we don't
free the memory from it and instead copy the pointer from each of these
items into the tbinfo structure).

Moving the allocation into the loop would also add unnecessary malloc
traffic, so I don't think we should add this.

@@ -15951,6 +15952,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
tbinfo->attfdwoptions[j]);
}
}
+
+		free(ftoptions);
+		free(srvname);
}

Yes, those could be free'd too.

I'll see about making those changes.

Thanks!

Stephen

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Stephen Frost (#2)
Re: minor leaks in pg_dump (PG tarball 10.6)

Stephen Frost <sfrost@snowman.net> writes:

* Pavel Raiskup (praiskup@redhat.com) wrote:

-			attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
...
+				attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));

This change doesn't seem to make any sense to me..? If anything, seems
like we'd end up overallocating memory *after* this change, where we
don't today (though an analyzer tool might complain because we don't
free the memory from it and instead copy the pointer from each of these
items into the tbinfo structure).

Yeah, Coverity is exceedingly not smart about the method pg_dump uses
(in lots of places, not just here) of allocating an array and then
entering pointers to individual array elements into its long-lived
data structures. I concur that the proposed change is giving up a
lot of malloc overhead to silence an invalid complaint, and we
shouldn't do it.

The other two points seem probably valid, so I wonder why our own
Coverity runs haven't noticed them.

regards, tom lane

#4Stephen Frost
sfrost@snowman.net
In reply to: Tom Lane (#3)
1 attachment(s)
Re: minor leaks in pg_dump (PG tarball 10.6)

Greetings,

* Tom Lane (tgl@sss.pgh.pa.us) wrote:

Stephen Frost <sfrost@snowman.net> writes:

* Pavel Raiskup (praiskup@redhat.com) wrote:

-			attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));
...
+				attrdefs = (AttrDefInfo *) pg_malloc(numDefaults * sizeof(AttrDefInfo));

This change doesn't seem to make any sense to me..? If anything, seems
like we'd end up overallocating memory *after* this change, where we
don't today (though an analyzer tool might complain because we don't
free the memory from it and instead copy the pointer from each of these
items into the tbinfo structure).

Yeah, Coverity is exceedingly not smart about the method pg_dump uses
(in lots of places, not just here) of allocating an array and then
entering pointers to individual array elements into its long-lived
data structures. I concur that the proposed change is giving up a
lot of malloc overhead to silence an invalid complaint, and we
shouldn't do it.

Agreed, patch attached. If there aren't any more comments, I'll plan to
push this later today or tomorrow. I wasn't thinking we would backpatch
this, so if others feel differently, please let me know.

The other two points seem probably valid, so I wonder why our own
Coverity runs haven't noticed them.

Not sure.. Looks like Coverity (incorrectly) worries about srvname
being NULL and then dereferenced inside fmtId(), except that relkind
doesn't change between the switch() and the conditional where srvname is
used. Maybe that is masking the resource leak concern? I don't see it
complaining about ftoptions though, so really not sure what's going on
there. I can try to ask the Coverity admin folks, but they've yet to
respond to multiple requests I've made about linking in the v11 branch
with the others..

Thanks!

Stephen

Attachments:

fix-pg_dump-memory-leak_v1.patchtext/x-diff; charset=us-asciiDownload
From b3551d31f00ac802392aa1982ed0045d4459bbad Mon Sep 17 00:00:00 2001
From: Stephen Frost <sfrost@snowman.net>
Date: Wed, 5 Dec 2018 11:53:44 -0500
Subject: [PATCH] Cleanup minor pg_dump memory leaks

In dumputils, we may have successfully parsed the acls when we discover
that we can't parse the reverse ACLs and then return- check and free
aclitems if that happens.

In dumpTableSchema, move ftoptions and srvname under the relkind !=
RELKIND_VIEW branch (since they're only used there) and then check if
they've been allocated and, if so, free them at the end of that block.

Pointed out by Pavel Raiskup, though I didn't use those patches.

Discussion: https://postgr.es/m/2183976.vkCJMhdhmF@nb.usersys.redhat.com
---
 src/bin/pg_dump/dumputils.c |  2 ++
 src/bin/pg_dump/pg_dump.c   | 14 ++++++++------
 2 files changed, 10 insertions(+), 6 deletions(-)

diff --git a/src/bin/pg_dump/dumputils.c b/src/bin/pg_dump/dumputils.c
index 8a93ace9fa..475d6dbd73 100644
--- a/src/bin/pg_dump/dumputils.c
+++ b/src/bin/pg_dump/dumputils.c
@@ -95,6 +95,8 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
 	{
 		if (!parsePGArray(racls, &raclitems, &nraclitems))
 		{
+			if (aclitems)
+				free(aclitems);
 			if (raclitems)
 				free(raclitems);
 			return false;
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index d583154fba..637c79af48 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -15303,8 +15303,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	int			actual_atts;	/* number of attrs in this CREATE statement */
 	const char *reltypename;
 	char	   *storage;
-	char	   *srvname;
-	char	   *ftoptions;
 	int			j,
 				k;
 
@@ -15361,6 +15359,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	}
 	else
 	{
+		char	   *ftoptions = NULL;
+		char	   *srvname = NULL;
+
 		switch (tbinfo->relkind)
 		{
 			case RELKIND_FOREIGN_TABLE:
@@ -15397,13 +15398,9 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 				}
 			case RELKIND_MATVIEW:
 				reltypename = "MATERIALIZED VIEW";
-				srvname = NULL;
-				ftoptions = NULL;
 				break;
 			default:
 				reltypename = "TABLE";
-				srvname = NULL;
-				ftoptions = NULL;
 		}
 
 		numParents = tbinfo->numParents;
@@ -15951,6 +15948,11 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 								  tbinfo->attfdwoptions[j]);
 			}
 		}
+
+		if (ftoptions)
+			free(ftoptions);
+		if (srvname)
+			free(srvname);
 	}
 
 	/*
-- 
2.17.1

#5Pavel Raiskup
praiskup@redhat.com
In reply to: Stephen Frost (#2)
Re: minor leaks in pg_dump (PG tarball 10.6)

On Wednesday, December 5, 2018 4:59:18 PM CET Stephen Frost wrote:

This change doesn't seem to make any sense to me..? If anything, seems
like we'd end up overallocating memory *after* this change, where we
don't today (though an analyzer tool might complain because we don't
free the memory from it and instead copy the pointer from each of these
items into the tbinfo structure).

Correct, I haven't think that one through. I was confused that some items
related to the dropped columns could be unreferenced. But those are
anyways allocated as a solid block with others (not intended to be ever
free()'d). Feel free to ignore that.

Thanks for looking at this!
Pavel

#6Stephen Frost
sfrost@snowman.net
In reply to: Pavel Raiskup (#5)
Re: minor leaks in pg_dump (PG tarball 10.6)

Greetings,

* Pavel Raiskup (praiskup@redhat.com) wrote:

On Wednesday, December 5, 2018 4:59:18 PM CET Stephen Frost wrote:

This change doesn't seem to make any sense to me..? If anything, seems
like we'd end up overallocating memory *after* this change, where we
don't today (though an analyzer tool might complain because we don't
free the memory from it and instead copy the pointer from each of these
items into the tbinfo structure).

Correct, I haven't think that one through. I was confused that some items
related to the dropped columns could be unreferenced. But those are
anyways allocated as a solid block with others (not intended to be ever
free()'d). Feel free to ignore that.

Right.

I've pushed the other changes.

Thanks!

Stephen