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));
&nbsp; &nbsp; pfree(pgstup);&nbsp; /* <-- 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:


&nbsp; &nbsp; typedef struct HeapTupleData {
&nbsp; &nbsp; &nbsp; &nbsp; uint32&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; t_len;
&nbsp; &nbsp; &nbsp; &nbsp; ItemPointerData t_self;
&nbsp; &nbsp; &nbsp; &nbsp; Oid&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 
&nbsp;t_tableOid;
&nbsp; &nbsp; &nbsp; &nbsp; HeapTupleHeader t_data;
&nbsp; &nbsp; } 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:


&nbsp; &nbsp; -&nbsp; &nbsp; pfree(pgstup);
&nbsp; &nbsp; +&nbsp; &nbsp; heap_freetuple(pgstup);


Patch:
======
---
&nbsp;src/backend/statistics/extended_stats_funcs.c | 2 +-
&nbsp;1 file changed, 1 insertion(+), 1 deletion(-)


diff --git a/src/backend/statistics/extended_stats_funcs.c 
b/src/backend/statistics/extended_stats_funcs.c
index 0ec77a6..9279904 100644
--- a/src/backend/statistics/extended_stats_funcs.c
+++ b/src/backend/statistics/extended_stats_funcs.c
@@ -1509,7 +1509,7 @@ import_pg_statistic(Relation pgsd, JsonbContainer *cont,
&nbsp;  pgstup = heap_form_tuple(RelationGetDescr(pgsd), values, nulls);
&nbsp;  pgstdat = heap_copy_tuple_as_datum(pgstup, RelationGetDescr(pgsd));
&nbsp;
-       pfree(pgstup);
+       heap_freetuple(pgstup);
&nbsp;
&nbsp;  *pg_statistic_ok = true;
&nbsp;
--


Regards,
Yonghao Lee

Attachment: 0001-Fix-improper-tuple-deallocation-in-import_pg_statist.patch
Description: Binary data

Reply via email to