Possible dereference after null check (src/backend/executor/ExecUtils.c)

From: Ranier Vilela <ranier(dot)vf(at)gmail(dot)com>
To: Pg Hackers <pgsql-hackers(at)postgresql(dot)org>
Subject: Possible dereference after null check (src/backend/executor/ExecUtils.c)
Date: 2021-02-10 22:54:46
Message-ID: CAEudQAoz67_xF2dbQRC56e28Ohq_8wrJXd7FnOs=wOETbT_Rdg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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_tupdesc, tupdesc
);
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(map, slot,
1752

MakeTupleTableSlot(tupdesc, &TTSOpsVirtual));
1753 modifiedCols = bms_union(ExecGetInsertedCols(rootrel,
estate),
1754
ExecGetUpdatedCols(rootrel, estate));
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
<https://scan6.coverity.com/eventId=32356039-3&modelId=32356039-0&fileInstanceId=112435213&filePath=%2Fdll%2Fpostgres%2Fsrc%2Fbackend%2Fexecutor%2FexecUtils.c&fileStart=1230&fileEnd=1255>
]
1760 modifiedCols = bms_union(ExecGetInsertedCols(
resultRelInfo, estate),
1761
ExecGetUpdatedCols(resultRelInfo, estate));
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

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Ranier Vilela 2021-02-10 23:12:38 Possible dereference null return (src/backend/replication/logical/reorderbuffer.c)
Previous Message Bruce Momjian 2021-02-10 22:43:44 Re: partial heap only tuples