On 3/5/26 01:40, yonghao_lee wrote:
> Hi hackers,
> 
> I found a tuple deallocation issue in the import_pg_statistic() function
> in src/backend/statistics/extended_stats_funcs.c. The code uses pfree()
> to release a
> HeapTuple, which doesn't properly free the underlying tuple data.
> 
> Bug Description:
> ================
> 
> In import_pg_statistic(), after heap_form_tuple() creates a HeapTuple and
> heap_copy_tuple_as_datum() copies it to a Datum, the code attempts to free
> the temporary HeapTuple using pfree():
> 
>     pgstup = heap_form_tuple(RelationGetDescr(pgsd), values, nulls);
>     pgstdat = heap_copy_tuple_as_datum(pgstup, RelationGetDescr(pgsd));
>     pfree(pgstup);  /* <-- BUG: Improper tuple release */
> 
> The Problem:
> ============
> 
> HeapTuple is a pointer to HeapTupleData structure, which contains a nested
> pointer t_data pointing to the actual tuple header and data:
> 
>     typedef struct HeapTupleData {
>         uint32          t_len;
>         ItemPointerData t_self;
>         Oid             t_tableOid;
>         HeapTupleHeader t_data;
>     } HeapTupleData;
> 
> Using pfree(pgstup) only frees the HeapTupleData structure itself
> , but leaves the underlying tuple data unfreed.
> 
> The Fix:
> ========
> 
> Replace pfree(pgstup) with heap_freetuple(pgstup), which properly frees both
> the HeapTupleData structure and the underlying t_data:
> 
>     -    pfree(pgstup);
>     +    heap_freetuple(pgstup);
> 

Except that heap_freetuple is defined like this:

void
heap_freetuple(HeapTuple htup)
{
    pfree(htup);
}

so this does not change anything. This report seems to miss how tuples
are allocated in heap_form_tuple.



-- 
Tomas Vondra



Reply via email to