Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit3acd059

Browse files
committed
Fix exception safety bug in typcache.c.
If an out-of-memory error was thrown at an unfortunate time,ensure_record_cache_typmod_slot_exists() could leak memory and leavebehind a global state that produced an infinite loop on the next call.Fix by merging RecordCacheArray and RecordIdentifierArray into a singlearray. With only one allocation or re-allocation, there is nointermediate state.Back-patch to all supported releases.Reported-by: "James Pang (chaolpan)" <chaolpan@cisco.com>Reviewed-by: Michael Paquier <michael@paquier.xyz>Discussion:https://postgr.es/m/PH0PR11MB519113E738814BDDA702EDADD6EFA%40PH0PR11MB5191.namprd11.prod.outlook.com
1 parent522a31a commit3acd059

File tree

2 files changed

+28
-21
lines changed

2 files changed

+28
-21
lines changed

‎src/backend/utils/cache/typcache.c

Lines changed: 27 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -273,10 +273,15 @@ static const dshash_parameters srtr_typmod_table_params = {
273273
/* hashtable for recognizing registered record types */
274274
staticHTAB*RecordCacheHash=NULL;
275275

276-
/* arrays of info about registered record types, indexed by assigned typmod */
277-
staticTupleDesc*RecordCacheArray=NULL;
278-
staticuint64*RecordIdentifierArray=NULL;
279-
staticint32RecordCacheArrayLen=0;/* allocated length of above arrays */
276+
typedefstructRecordCacheArrayEntry
277+
{
278+
uint64id;
279+
TupleDesctupdesc;
280+
}RecordCacheArrayEntry;
281+
282+
/* array of info about registered record types, indexed by assigned typmod */
283+
staticRecordCacheArrayEntry*RecordCacheArray=NULL;
284+
staticint32RecordCacheArrayLen=0;/* allocated length of above array */
280285
staticint32NextRecordTypmod=0;/* number of entries used */
281286

282287
/*
@@ -1703,19 +1708,20 @@ ensure_record_cache_typmod_slot_exists(int32 typmod)
17031708
{
17041709
if (RecordCacheArray==NULL)
17051710
{
1706-
RecordCacheArray= (TupleDesc*)
1707-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(TupleDesc));
1708-
RecordIdentifierArray= (uint64*)
1709-
MemoryContextAllocZero(CacheMemoryContext,64*sizeof(uint64));
1711+
RecordCacheArray= (RecordCacheArrayEntry*)
1712+
MemoryContextAllocZero(CacheMemoryContext,
1713+
64*sizeof(RecordCacheArrayEntry));
17101714
RecordCacheArrayLen=64;
17111715
}
17121716

17131717
if (typmod >=RecordCacheArrayLen)
17141718
{
17151719
int32newlen=pg_nextpower2_32(typmod+1);
17161720

1717-
RecordCacheArray=repalloc0_array(RecordCacheArray,TupleDesc,RecordCacheArrayLen,newlen);
1718-
RecordIdentifierArray=repalloc0_array(RecordIdentifierArray,uint64,RecordCacheArrayLen,newlen);
1721+
RecordCacheArray=repalloc0_array(RecordCacheArray,
1722+
RecordCacheArrayEntry,
1723+
RecordCacheArrayLen,
1724+
newlen);
17191725
RecordCacheArrayLen=newlen;
17201726
}
17211727
}
@@ -1753,8 +1759,8 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
17531759
{
17541760
/* It is already in our local cache? */
17551761
if (typmod<RecordCacheArrayLen&&
1756-
RecordCacheArray[typmod]!=NULL)
1757-
returnRecordCacheArray[typmod];
1762+
RecordCacheArray[typmod].tupdesc!=NULL)
1763+
returnRecordCacheArray[typmod].tupdesc;
17581764

17591765
/* Are we attached to a shared record typmod registry? */
17601766
if (CurrentSession->shared_typmod_registry!=NULL)
@@ -1780,19 +1786,19 @@ lookup_rowtype_tupdesc_internal(Oid type_id, int32 typmod, bool noError)
17801786
* Our local array can now point directly to the TupleDesc
17811787
* in shared memory, which is non-reference-counted.
17821788
*/
1783-
RecordCacheArray[typmod]=tupdesc;
1789+
RecordCacheArray[typmod].tupdesc=tupdesc;
17841790
Assert(tupdesc->tdrefcount==-1);
17851791

17861792
/*
17871793
* We don't share tupdesc identifiers across processes, so
17881794
* assign one locally.
17891795
*/
1790-
RecordIdentifierArray[typmod]=++tupledesc_id_counter;
1796+
RecordCacheArray[typmod].id=++tupledesc_id_counter;
17911797

17921798
dshash_release_lock(CurrentSession->shared_typmod_table,
17931799
entry);
17941800

1795-
returnRecordCacheArray[typmod];
1801+
returnRecordCacheArray[typmod].tupdesc;
17961802
}
17971803
}
17981804
}
@@ -2005,10 +2011,10 @@ assign_record_type_typmod(TupleDesc tupDesc)
20052011
ensure_record_cache_typmod_slot_exists(entDesc->tdtypmod);
20062012
}
20072013

2008-
RecordCacheArray[entDesc->tdtypmod]=entDesc;
2014+
RecordCacheArray[entDesc->tdtypmod].tupdesc=entDesc;
20092015

20102016
/* Assign a unique tupdesc identifier, too. */
2011-
RecordIdentifierArray[entDesc->tdtypmod]=++tupledesc_id_counter;
2017+
RecordCacheArray[entDesc->tdtypmod].id=++tupledesc_id_counter;
20122018

20132019
/* Fully initialized; create the hash table entry */
20142020
recentry= (RecordCacheEntry*)hash_search(RecordCacheHash,
@@ -2057,10 +2063,10 @@ assign_record_type_identifier(Oid type_id, int32 typmod)
20572063
* It's a transient record type, so look in our record-type table.
20582064
*/
20592065
if (typmod >=0&&typmod<RecordCacheArrayLen&&
2060-
RecordCacheArray[typmod]!=NULL)
2066+
RecordCacheArray[typmod].tupdesc!=NULL)
20612067
{
2062-
Assert(RecordIdentifierArray[typmod]!=0);
2063-
returnRecordIdentifierArray[typmod];
2068+
Assert(RecordCacheArray[typmod].id!=0);
2069+
returnRecordCacheArray[typmod].id;
20642070
}
20652071

20662072
/* For anonymous or unrecognized record type, generate a new ID */
@@ -2140,7 +2146,7 @@ SharedRecordTypmodRegistryInit(SharedRecordTypmodRegistry *registry,
21402146
TupleDesctupdesc;
21412147
boolfound;
21422148

2143-
tupdesc=RecordCacheArray[typmod];
2149+
tupdesc=RecordCacheArray[typmod].tupdesc;
21442150
if (tupdesc==NULL)
21452151
continue;
21462152

‎src/tools/pgindent/typedefs.list

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2251,6 +2251,7 @@ ReadLocalXLogPageNoWaitPrivate
22512251
ReadReplicationSlotCmd
22522252
ReassignOwnedStmt
22532253
RecheckForeignScan_function
2254+
RecordCacheArrayEntry
22542255
RecordCacheEntry
22552256
RecordCompareData
22562257
RecordIOData

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp