Fix potential NULL pointer dereference in getIdentitySequence()

The function invokes SearchSysCacheAttNum() and SearchSysCacheAttName().
They may respectively return 0 for the attribute number or NULL for
the attribute name if the attribute does not exist, without any kind of
error handling.  The common practice is to check that the data retrieved
from the syscache is valid.  There is no risk of NULL pointer
dereferences currently, but let's stick to the practice of making sure
that this data is always valid, to catch future inconsistency mistakes.
The code is switched to use get_attnum() and get_attname(), and adds
some error handling.

Oversight in 509199587d.

Reported-by: Ranier Vilela
Author: Ashutosh Bapat
Discussion: https://postgr.es/m/CAEudQAqh_RZqoFcYKso5d9VhF-Vd64_ZodfQ_2zSusszkEmyRg@mail.gmail.com
This commit is contained in:
Michael Paquier 2024-05-26 20:58:27 +09:00
parent 945ec4c4bc
commit 8285b484a4
1 changed files with 7 additions and 13 deletions

View File

@ -945,7 +945,7 @@ getOwnedSequences(Oid relid)
Oid
getIdentitySequence(Relation rel, AttrNumber attnum, bool missing_ok)
{
Oid relid;
Oid relid = RelationGetRelid(rel);
List *seqlist;
/*
@ -954,22 +954,16 @@ getIdentitySequence(Relation rel, AttrNumber attnum, bool missing_ok)
*/
if (RelationGetForm(rel)->relispartition)
{
List *ancestors =
get_partition_ancestors(RelationGetRelid(rel));
HeapTuple ctup = SearchSysCacheAttNum(RelationGetRelid(rel), attnum);
const char *attname = NameStr(((Form_pg_attribute) GETSTRUCT(ctup))->attname);
HeapTuple ptup;
List *ancestors = get_partition_ancestors(relid);
const char *attname = get_attname(relid, attnum, false);
relid = llast_oid(ancestors);
ptup = SearchSysCacheAttName(relid, attname);
attnum = ((Form_pg_attribute) GETSTRUCT(ptup))->attnum;
ReleaseSysCache(ctup);
ReleaseSysCache(ptup);
attnum = get_attnum(relid, attname);
if (attnum == InvalidAttrNumber)
elog(ERROR, "cache lookup failed for attribute \"%s\" of relation %u",
attname, relid);
list_free(ancestors);
}
else
relid = RelationGetRelid(rel);
seqlist = getOwnedSequences_internal(relid, attnum, DEPENDENCY_INTERNAL);
if (list_length(seqlist) > 1)