Fix potential NULL pointer dereference in getIdentitySequence()
authorMichael Paquier <[email protected]>
Sun, 26 May 2024 11:58:27 +0000 (20:58 +0900)
committerMichael Paquier <[email protected]>
Sun, 26 May 2024 11:58:27 +0000 (20:58 +0900)
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 509199587df7.

Reported-by: Ranier Vilela
Author: Ashutosh Bapat
Discussion: https://postgr.es/m/CAEudQAqh_RZqoFcYKso5d9VhF-Vd64_ZodfQ_2zSusszkEmyRg@mail.gmail.com

src/backend/catalog/pg_depend.c

index 5366f7820c12ef1c6928b98ffaa249389dcb3b2b..cfd7ef51dfa29b7ba4c62ca23a8ec387271e0502 100644 (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)