aboutsummaryrefslogtreecommitdiff
path: root/src/backend/commands
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2011-09-06 14:35:55 -0400
committerTom Lane <tgl@sss.pgh.pa.us>2011-09-06 14:38:11 -0400
commit3cfb60272ce6dc95ea367446fb20db91ed05476e (patch)
tree0a0e2d47d061d786860e0fcae4b793ee8d9c6ece /src/backend/commands
parentf85efeef2455e788092b497f7b8d6f9246b1cdfc (diff)
downloadpostgresql-3cfb60272ce6dc95ea367446fb20db91ed05476e.tar.gz
postgresql-3cfb60272ce6dc95ea367446fb20db91ed05476e.zip
Avoid possibly accessing off the end of memory in examine_attribute().
Since the last couple of columns of pg_type are often NULL, sizeof(FormData_pg_type) can be an overestimate of the actual size of the tuple data part. Therefore memcpy'ing that much out of the catalog cache, as analyze.c was doing, poses a small risk of copying past the end of memory and incurring SIGSEGV. No such crash has been identified in the field, but we've certainly seen the equivalent happen in other code paths, so patch this one all the way back. Per valgrind testing by Noah Misch, though this is not his proposed patch. I chose to use SearchSysCacheCopy1 rather than inventing special-purpose infrastructure for copying only the minimal part of a pg_type tuple.
Diffstat (limited to 'src/backend/commands')
-rw-r--r--src/backend/commands/analyze.c12
1 files changed, 5 insertions, 7 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c
index 5c7cc650e3e..c730cfc7791 100644
--- a/src/backend/commands/analyze.c
+++ b/src/backend/commands/analyze.c
@@ -702,14 +702,12 @@ examine_attribute(Relation onerel, int attnum)
stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats));
stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE);
memcpy(stats->attr, attr, ATTRIBUTE_TUPLE_SIZE);
- typtuple = SearchSysCache(TYPEOID,
- ObjectIdGetDatum(attr->atttypid),
- 0, 0, 0);
+ typtuple = SearchSysCacheCopy(TYPEOID,
+ ObjectIdGetDatum(attr->atttypid),
+ 0, 0, 0);
if (!HeapTupleIsValid(typtuple))
elog(ERROR, "cache lookup failed for type %u", attr->atttypid);
- stats->attrtype = (Form_pg_type) palloc(sizeof(FormData_pg_type));
- memcpy(stats->attrtype, GETSTRUCT(typtuple), sizeof(FormData_pg_type));
- ReleaseSysCache(typtuple);
+ stats->attrtype = (Form_pg_type) GETSTRUCT(typtuple);
stats->anl_context = anl_context;
stats->tupattnum = attnum;
@@ -725,7 +723,7 @@ examine_attribute(Relation onerel, int attnum)
if (!ok || stats->compute_stats == NULL || stats->minrows <= 0)
{
- pfree(stats->attrtype);
+ heap_freetuple(typtuple);
pfree(stats->attr);
pfree(stats);
return NULL;