Possible dereference after null check (src/backend/executor/ExecUtils.c) - Mailing list pgsql-hackers

From Ranier Vilela
Subject Possible dereference after null check (src/backend/executor/ExecUtils.c)
Date
Msg-id CAEudQAoz67_xF2dbQRC56e28Ohq_8wrJXd7FnOs=wOETbT_Rdg@mail.gmail.com
Whole thread Raw
Responses Re: Possible dereference after null check (src/backend/executor/ExecUtils.c)
List pgsql-hackers
Hi,

Per Coverity.

The functions ExecGetInsertedCols and ExecGetUpdatedCols at ExecUtils.c
only are safe to call if the variable "ri_RangeTableIndex" is  != 0.

Otherwise a possible Dereference after null check (FORWARD_NULL) can be raised.

Exemple:

void
1718ExecPartitionCheckEmitError(ResultRelInfo *resultRelInfo,
1719                                                        TupleTableSlot *slot,
1720                                                        EState *estate)
1721{
1722        Oid                     root_relid;
1723        TupleDesc       tupdesc;
1724        char       *val_desc;
1725        Bitmapset  *modifiedCols;
1726
1727        /*
1728         * If the tuple has been routed, it's been converted to the partition's
1729         * rowtype, which might differ from the root table's.  We must convert it
1730         * back to the root table's rowtype so that val_desc in the error message
1731         * matches the input tuple.
1732         */
    
1. Condition resultRelInfo->ri_RootResultRelInfo, taking false branch.
    
2. var_compare_op: Comparing resultRelInfo->ri_RootResultRelInfo to null implies that resultRelInfo->ri_RootResultRelInfo might be null.
1733        if (resultRelInfo->ri_RootResultRelInfo)
1734        {
1735                ResultRelInfo *rootrel = resultRelInfo->ri_RootResultRelInfo;
1736                TupleDesc       old_tupdesc;
1737                AttrMap    *map;
1738
1739                root_relid = RelationGetRelid(rootrel->ri_RelationDesc);
1740                tupdesc = RelationGetDescr(rootrel->ri_RelationDesc);
1741
1742                old_tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
1743                /* a reverse map */
1744                map = build_attrmap_by_name_if_req(old_tupdesctupdesc);
1745
1746                /*
1747                 * Partition-specific slot's tupdesc can't be changed, so allocate a
1748                 * new one.
1749                 */
1750                if (map != NULL)
1751                        slot = execute_attr_map_slot(mapslot,
1752                                                                                 MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1753                modifiedCols = bms_union(ExecGetInsertedCols(rootrelestate),
1754                                                                 ExecGetUpdatedCols(rootrelestate));
1755        }
1756        else
1757        {
1758                root_relid = RelationGetRelid(resultRelInfo->ri_RelationDesc);
1759                tupdesc = RelationGetDescr(resultRelInfo->ri_RelationDesc);
    
CID 1446241 (#1 of 1): Dereference after null check (FORWARD_NULL)3. var_deref_model: Passing resultRelInfo to ExecGetInsertedCols, which dereferences null resultRelInfo->ri_RootResultRelInfo. [show details]
1760                modifiedCols = bms_union(ExecGetInsertedCols(resultRelInfoestate),
1761                                                                 ExecGetUpdatedCols(resultRelInfoestate));
1762        }
1763
1764        val_desc = ExecBuildSlotValueDescription(root_relid,
1765                                                                                         slot,
1766                                                                                         tupdesc,
1767                                                                                         modifiedCols,
1768                                                                                         64);
1769        ereport(ERROR,
1770                        (errcode(ERRCODE_CHECK_VIOLATION),
1771                         errmsg("new row for relation \"%s\" violates partition constraint",
1772                                        RelationGetRelationName(resultRelInfo->ri_RelationDesc)),
1773                         val_desc ? errdetail("Failing row contains %s.", val_desc) : 0,
1774                         errtable(resultRelInfo->ri_RelationDesc)));
1775}

regards,
Ranier Viela

pgsql-hackers by date:

Previous
From: Bruce Momjian
Date:
Subject: Re: partial heap only tuples
Next
From: Ranier Vilela
Date:
Subject: Possible dereference null return (src/backend/replication/logical/reorderbuffer.c)