postgres.git / summary / log / commit / refs

commit    460bfd07b38f6495314c01499fca49f5f4a68a38
Author:   Tom Lane <tgl@sss.pgh.pa.us>
Date:     Tue Sep 06 18:35:27 2011 +0000
First released in: 9.2.0, 8.2.22, 8.3.16, 8.4.9, 9.0.5, 9.1.0

    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.


src/backend/commands/analyze.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index f5dfb5f19f1..a930a67d626 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -845,12 +845,11 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr) stats->attrtypmod = attr->atttypmod; } - typtuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(stats->attrtypid)); + typtuple = SearchSysCacheCopy1(TYPEOID, + ObjectIdGetDatum(stats->attrtypid)); if (!HeapTupleIsValid(typtuple)) elog(ERROR, "cache lookup failed for type %u", stats->attrtypid); - 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; @@ -879,7 +878,7 @@ examine_attribute(Relation onerel, int attnum, Node *index_expr) if (!ok || stats->compute_stats == NULL || stats->minrows <= 0) { - pfree(stats->attrtype); + heap_freetuple(typtuple); pfree(stats->attr); pfree(stats); return NULL; [parent: 94bf47db8ffc]